İş parçacığına çok geç, ancak Açısal öncesi kullandığım bir teknik, JSON ve JS'nin toplama anahtarlarına dinamik olarak başvurma ve ortamın devredilemez gerçeklerini (ana makine sunucusu adı, geçerli tarayıcı dili) kullanma esnekliğinden yararlanmaktır. vb.) bir JSON veri yapısı içinde sonlandırılmış anahtar adlarını seçici olarak ayırmak / tercih etmek için girişler olarak.
Bu, yalnızca dağıtım ortamı bağlamını (OP başına) değil, aynı anda ve (ideal olarak) tek bir yapılandırma bildirimi içinde, çoğaltma olmadan ve net bir şekilde gerekli olan i18n veya diğer varyansları sağlamak için herhangi bir keyfi bağlam (dil gibi) sağlar.
10 LINES VANILLA JS HAKKINDA
Aşırı basitleştirilmiş ancak klasik örnek: JSON biçimli özellikler dosyasındaki, ana makine sunucusunun (natch) da değişeceği ortama göre değişen bir API uç noktası temel URL'si:
...
'svcs': {
'VER': '2.3',
'API@localhost': 'http://localhost:9090/',
'API@www.uat.productionwebsite.com': 'https://www.uat.productionwebsite.com:9090/res/',
'API@www.productionwebsite.com': 'https://www.productionwebsite.com:9090/api/res/'
},
...
Ayrımcılık işlevinin anahtarı, istekte bulunan sunucu ana bilgisayar adıdır.
Bu, doğal olarak, kullanıcının dil ayarlarına bağlı olarak ek bir anahtarla birleştirilebilir:
...
'app': {
'NAME': 'Ferry Reservations',
'NAME@fr': 'Réservations de ferry',
'NAME@de': 'Fähren Reservierungen'
},
...
Ayrımcılık / tercih kapsamı, "temel" anahtarın yalnızca işleve veya tüm yapının girişleri için eşleşen bir anahtar + sonek varsa ve bu yapının kendisinin üzerine yazıldığı ayrı tuşlarla (yukarıdaki gibi) sınırlandırılabilir. ayrımcılık / tercih soneklerini eşleştirmek için özyinelemeli olarak ayrıştırılır:
'help': {
'BLURB': 'This pre-production environment is not supported. Contact Development Team with questions.',
'PHONE': '808-867-5309',
'EMAIL': 'coder.jen@lostnumber.com'
},
'help@www.productionwebsite.com': {
'BLURB': 'Please contact Customer Service Center',
'BLURB@fr': 'S\'il vous plaît communiquer avec notre Centre de service à la clientèle',
'BLURB@de': 'Bitte kontaktieren Sie unseren Kundendienst!!1!',
'PHONE': '1-800-CUS-TOMR',
'EMAIL': 'customer.service@productionwebsite.com'
},
Dolayısıyla, üretim web sitesini ziyaret eden bir kullanıcının Almanca ( de ) dil tercihi ayarı varsa, yukarıdaki yapılandırma şu şekilde daraltılır:
'help': {
'BLURB': 'Bitte kontaktieren Sie unseren Kundendienst!!1!',
'PHONE': '1-800-CUS-TOMR',
'EMAIL': 'customer.service@productionwebsite.com'
},
Böyle büyülü bir tercih / ayrımcılık JSON-yeniden yazma işlevi neye benziyor? Fazla değil:
// prefer(object,suffix|[suffixes]) by/par/durch storsoc
// prefer({ a: 'apple', a@env: 'banana', b: 'carrot' },'env') -> { a: 'banana', b: 'carrot' }
function prefer(o,sufs) {
for (var key in o) {
if (!o.hasOwnProperty(key)) continue; // skip non-instance props
if(key.split('@')[1]) { // suffixed!
// replace root prop with the suffixed prop if among prefs
if(o[key] && sufs.indexOf(key.split('@')[1]) > -1) o[key.split('@')[0]] = JSON.parse(JSON.stringify(o[key]));
// and nuke the suffixed prop to tidy up
delete o[key];
// continue with root key ...
key = key.split('@')[0];
}
// ... in case it's a collection itself, recurse it!
if(o[key] && typeof o[key] === 'object') prefer(o[key],sufs);
};
};
Açısal ve Açısal web sitelerini içeren uygulamalarımızda, JSON'u tercihli () işlevi dahil olmak üzere kendi kendini yürüten bir JS kapanışına yerleştirerek ve ana bilgisayar adı ve dil kodu (ve ihtiyacınız olabilecek ek isteğe bağlı ekleri kabul eder):
(function(prefs){ var props = {
'svcs': {
'VER': '2.3',
'API@localhost': 'http://localhost:9090/',
'API@www.uat.productionwebsite.com': 'https://www.uat.productionwebsite.com:9090/res/',
'API@www.productionwebsite.com': 'https://www.productionwebsite.com:9090/api/res/'
},
...
/* yadda yadda moar JSON und bisque */
function prefer(o,sufs) {
// body of prefer function, broken for e.g.
};
// convert string and comma-separated-string to array .. and process it
prefs = [].concat( ( prefs.split ? prefs.split(',') : prefs ) || []);
prefer(props,prefs);
window.app_props = JSON.parse(JSON.stringify(props));
})([location.hostname, ((window.navigator.userLanguage || window.navigator.language).split('-')[0]) ] );
Açısal olmayan bir sitenin artık daraltılmış (@ soneki anahtar yok) window.app_props ifadesi olacaktır.
Açısal bir site, bir bootstrap / init adımı olarak, ölü bırakılan sahne nesnesini $ rootScope'a kopyalar ve (isteğe bağlı olarak) global / pencere kapsamından yok eder
app.constant('props',angular.copy(window.app_props || {})).run( function ($rootScope,props) { $rootScope.props = props; delete window.app_props;} );
daha sonra kontrolörlere enjekte edilecek:
app.controller('CtrlApp',function($log,props){ ... } );
veya görünümlerde ciltlerden bahsedilir:
<span>{{ props.help.blurb }} {{ props.help.email }}</span>
Uyarılar? @ Karakteri geçerli JS / JSON değişkeni / anahtar adlandırması değil, şimdiye kadar kabul edildi. Bu bir anlaşma kırıcı ise, "__" (çift alt çizgi) gibi herhangi bir konvansiyonun yerine sadık kaldığınız sürece kullanın.
Teknik, sunucu tarafında uygulanabilir, Java veya C # 'a taşınabilir, ancak verimliliğiniz / kompaktlığınız değişebilir.
Alternatif olarak, işlev / kural, ön uç derleme komut dosyanızın bir parçası olabilir, böylece tam kanlı tüm ortam / tüm dilde JSON kablo üzerinden iletilmez.
GÜNCELLEME
Bu tekniğin bir anahtara birden çok sonek vermesine izin vermek, koleksiyonları kullanmaya zorlanmaktan kaçınmak için (yine de istediğiniz kadar derinlemesine yapabilirsiniz) ve tercih edilen eklerin sırasını onurlandırmak için bu tekniği kullandık.
Örnek (ayrıca bkz. Çalışan jsFiddle ):
var o = { 'a':'apple', 'a@dev':'apple-dev', 'a@fr':'pomme',
'b':'banana', 'b@fr':'banane', 'b@dev&fr':'banane-dev',
'c':{ 'o':'c-dot-oh', 'o@fr':'c-point-oh' }, 'c@dev': { 'o':'c-dot-oh-dev', 'o@fr':'c-point-oh-dev' } };
/*1*/ prefer(o,'dev'); // { a:'apple-dev', b:'banana', c:{o:'c-dot-oh-dev'} }
/*2*/ prefer(o,'fr'); // { a:'pomme', b:'banane', c:{o:'c-point-oh'} }
/*3*/ prefer(o,'dev,fr'); // { a:'apple-dev', b:'banane-dev', c:{o:'c-point-oh-dev'} }
/*4*/ prefer(o,['fr','dev']); // { a:'pomme', b:'banane-dev', c:{o:'c-point-oh-dev'} }
/*5*/ prefer(o); // { a:'apple', b:'banana', c:{o:'c-dot-oh'} }
1/2 (temel kullanım) '@dev' tuşlarını tercih eder, diğer tüm eklenmiş tuşları atar
3 '@fr' yerine '@dev', diğerlerini '' dev & fr 'tercih eder
4 (3 ile aynı ancak '@dev' yerine '@fr' tercih eder)
5 tercih edilen ek yok, TÜM ekli özellikleri düşürüyor
Bunu, her bir ekli mülkü puanlayarak ve ekler üzerinde bir özelliğin değerini, özellikler üzerinde yineleme yaparken ve daha yüksek puanlı bir sonek bulurken ekli olmayan özelliğe yükselterek gerçekleştirir.
JSON'a derin kopyalamaya bağımlılığı kaldırmak ve yalnızca derinlemesine puanlama turunda hayatta kalan nesnelere yineleme dahil olmak üzere bu sürümdeki bazı verimlilikler:
function prefer(obj,suf) {
function pr(o,s) {
for (var p in o) {
if (!o.hasOwnProperty(p) || !p.split('@')[1] || p.split('@@')[1] ) continue; // ignore: proto-prop OR not-suffixed OR temp prop score
var b = p.split('@')[0]; // base prop name
if(!!!o['@@'+b]) o['@@'+b] = 0; // +score placeholder
var ps = p.split('@')[1].split('&'); // array of property suffixes
var sc = 0; var v = 0; // reset (running)score and value
while(ps.length) {
// suffix value: index(of found suffix in prefs)^10
v = Math.floor(Math.pow(10,s.indexOf(ps.pop())));
if(!v) { sc = 0; break; } // found suf NOT in prefs, zero score (delete later)
sc += v;
}
if(sc > o['@@'+b]) { o['@@'+b] = sc; o[b] = o[p]; } // hi-score! promote to base prop
delete o[p];
}
for (var p in o) if(p.split('@@')[1]) delete o[p]; // remove scores
for (var p in o) if(typeof o[p] === 'object') pr(o[p],s); // recurse surviving objs
}
if( typeof obj !== 'object' ) return; // validate
suf = ( (suf || suf === 0 ) && ( suf.length || suf === parseFloat(suf) ) ? suf.toString().split(',') : []); // array|string|number|comma-separated-string -> array-of-strings
pr(obj,suf.reverse());
}
'ngconstant:development'
içinde'serve'
sen altında saatin config koyarsanız -'gruntfile'
olaraktasks: ['ngconstant:development']
size yeniden başlatma gerekmez -grunt serve
Eğer gruntfile geliştirme değişkenlerini güncelleştirme.