1

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

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.ta delayedT,它基于一个属性:

function delayedT(key) {
    return property depending on App.languageLoaded, to do Ember.I18n.t(key)
}

只要设置了应用程序标志,就会计算此属性:App.languageLoaded。每当语言文件完成加载时,我都会这样做App.set('languageLoaded', true),这会触发所有翻译。这样,翻译只会在正确的时间(当语言数据到达时)为应用程序执行一次。

这有意义吗?我将如何实现延迟T?

4

1 回答 1

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);
});

如果你真的想要的话,这里有一些使用 Promise 的方法,但我可能不会打扰。

于 2014-02-19T03:37:37.417 回答