使用属性的后期评估进行应用程序本

时间:2014-02-18 15:47:08

标签: ember.js ember-i18n

我有一堆控制器,其中一些属性是使用翻译库生成的:

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?

1 个答案:

答案 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,但我可能不会打扰。