我有一堆控制器,其中一些属性是使用翻译库生成的:
App.CallsStatusTotalsPerHourChartController = Ember.ArrayController.extend({
title: Ember.I18n.t('dashboard.calls-per-hour.title'),
subTitle: Ember.I18n.t('dashboard.calls-per-hour.subtitle'),
noDataText: Ember.I18n.t('dashboard.calls-per-hour.no-data'),
content: []
});
问题是语言文件尚未加载(需要一些时间),因此在定义时,Ember.I18n.t
没有数据,并且所有翻译都失败了。有几个解决方案,但对我来说似乎更简单的是:
我不会直接调用Ember.I18n.t
,而是调用delayedT
,它将基于属性:
function delayedT(key) {
return property depending on App.languageLoaded, to do Ember.I18n.t(key)
}
只要设置了应用程序标志,就会计算此属性:App.languageLoaded。每当语言文件加载完毕,我都会App.set('languageLoaded', true)
,这将触发所有翻译。这样,在适当的时间(语言数据到达时),应用程序只会执行一次翻译。
这有意义吗?我该如何实施delayedT?
答案 0 :(得分:2)
首先,我建议不要在App
全球范围内设置属性。
总的来说,您可以通过创建在加载语言时无效的计算属性来解决此问题。
这是一些未经测试的代码来说明这种方法。创建一个翻译类:
App.Translator = Ember.Object.extend({
languageLoaded: false,
translate: function(key){
if (this.get('languageLoaded')) {
return Ember.I18n.t(key);
}
}
});
将其注册为单身人士,并将其注入控制器:
Ember.Application.initializer({
name: 'setup translation',
initialize: function(container, application) {
application.register('translator:main', App.Translator);
container.injection('controller', 'translator', 'translator:main');
}
});
然后在您的控制器中,您可以拥有一个依赖于languageLoaded
属性的属性(因此当languageLoaded变为true时,它将失效并重新运行:
App.CallsStatusTotalsPerHourChartController = Ember.ArrayController.extend({
title: function(){
return this.get('translator').translate('dashboard.calls-per-hour.title');
}.property('translator.languageLoaded'),
});
您可以使用宏来缩短它:
function t(key){
return function(){
return this.get('translator').translate(key);
}.property('translator.languageLoaded')
}
App.CallsStatusTotalsPerHourChartController = Ember.ArrayController.extend({
title: t('dashboard.calls-per-hour.title'),
subTitle: t('dashboard.calls-per-hour. subtitle'),
noDataText: t('dashboard.calls-per-hour.no-data'),
content: []
});
当您的语言加载时,不要忘记查找翻译器并设置布尔值:
// yippee, my language finally loaded
Ember.run(function(){
this.container.lookup('translator:main').set('languageLoaded', true);
});
如果你真的想要,可以在这里使用promises,但我可能不会打扰。