我有一堆控制器,其中一些属性是用翻译库生成的:
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)
,这将触发所有翻译。这样,只需在正确的时间(当语言数据到达时)为应用程序执行一次翻译。
这有意义吗?我将如何实现延迟 T?
首先,我建议不要在全局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);
});
如果你真的想要,有很多方法可以在这里使用承诺,但我可能不会打扰。