Ember:动态切换到所选语言(使用i18n库)

时间:2013-08-05 18:35:14

标签: internationalization ember.js

我正在使用ember-i18n库来翻译整个应用程序中使用的静态字符串。由于语言文件相当大,我不想在应用程序启动时加载所有可能的语言词典。因此,我想在用户选择更改语言时动态加载字典。我做了第一个相当好的实现。

请参阅http://jsfiddle.net/cyclomarc/RYbNG/7/

启动应用时,会以英语呈现。您现在可以选择其中一个视图(“关于”或“信息”),这些视图也以英语呈现。单击“荷兰语”时,将加载荷兰语语言词典,并以正确的语言将应用程序重定向到索引路径。

似乎新的语言字符串仅在您转换到虚拟路线然后返回到您想要的路线时使用(在我的示例中,这总是'索引')。

updateLanguage: function (lang) {
    var _self = this;
    //Load correct dictionary and transition to index route
    $.getScript("http://libraries.azurewebsites.net/locales/dictionary_" + lang + ".js", function () {
      CLDR.defaultLanguage = lang;
      _self.transitionToRoute('I18redirect');
    });
  }

App.I18redirectRoute = Ember.Route.extend({
  activate: function () {
    this.transitionTo('index');
  }
});

我的问题:

  1. 这是重新加载view.template的最佳方式(转换为虚拟路线,然后激活转换为索引)?

  2. 有没有办法转换回您请求语言更改的路径(需要使用带有get(路径)的东西)?

  3. 我还想把红色div(应用程序插座)之外的字符串翻译成“。我转换回索引,但在这种情况下,应用程序模板没有重绘...可能是什么原因?

  4. 当您离开模板然后重新输入模板时,是否存在预期的行为,模板本身将使用所有语言字符串进行重建,或者只有在此期间语言被更改时才会出现这种情况?如何在控制台日志中跟踪这种带有新字符串的模板重建?

  5. 使其成为强大的切换解决方案的任何其他想法?

3 个答案:

答案 0 :(得分:0)

我还没有在我的应用程序中完成翻译,但我打算这样做。所以我也很想知道什么是最好的解决方案。我将用我目前的知识描述我目前的想法。

1)我将语言定义为顶级路线。

App.Router.map(function() {
    this.resource('language', {path:'/language/:lang_code'}, function() {
        // All other routes
    });
});

然后更改语言将是语言路由与相应语言代码的链接。我还将为此定义具有属性代码,名称,标志等的语言模型。显示语言选择按钮或下拉列表时,这也很方便。

此外,在加载子路由模型时,您已经知道了langugage是什么,您可以使用当前语言获取模型(例如,考虑每种语言不同的博客文章)。使用this.modelFor('language')获取任何子路径中的当前语言。

2)这很棘手。 AFAIK没有公共API来获取所有动态细分的当前网址。应用程序控制器中有currentPath属性,但它不包含动态路由变量。还有一些Ember内部变量,但我不会使用它们,因为它们可能会改变。您还可以调查当前路由器URL:this.get('router.url')。您也可以绕过ember并使用window.location.href直接读取URL。但我不会花太多时间在那上面。用户很少改变他们的语言(通常仅在第一次访问时),并且在语言更改时重定向到索引路径不是一个大问题。我会将它存储在cookie或本地存储中,然后不需要更改语言。如果Ember提供了简单易行的方法,那么您可以在以后轻松添加此功能。

3)我不会将任何内容放入应用程序模板中,因为它没有被翻译。使用语言模板而不是应用程序模板,然后在切换语言时应重新呈现所有内容。

4)我认为文本不会自动更新,因为它们目前不是双向绑定的。但它很好,因为对所有文本进行双向绑定不是一个好主意,因为它可以使系统变慢。所以只需将语言作为顶级路线,一切都应该正常工作:)

答案 1 :(得分:0)

您可以使用视图的rerender()方法,这样您就不必切换到虚拟网址:

updateLanguage: function(lang) {

    //Send xhr to get a dictionary for corresponding language
    this.getDictionary(lang).then(successCb, failureCb);

    //If dictionary was retrieved, set translations property and 
    function successCb(response) {
        Ember.I18n.translations = response;
        $.each(Ember.View.views, function(index, view) {
          view.rerender();
        });
    };

    function failureCb(response) {
        console.error('Dictionary for this language is not available');
    };
}

答案 2 :(得分:0)

我尝试了这里列出的所有方法,并且遇到了各种各样的问题。我找到了一个更优雅的黑客来完成这项工作。

CAVEAT:这只适用于使用Rails服务Ember(但可能适用于任何服务器端框架)。

在Rails中,i18n-js gem与Rails默认语言环境集成。 Ember中的动态切换是一个巨大的痛苦,因为您必须手动重绘所有视图或重置应用程序以在更改I18n.locale时更新语言。

我发现这样做的最好方法是在Ember加载之前使用Rails上设置的参数指定区域设置。

RAILS配置:

让你的余烬#index控制器动作看起来像这样:

def index
  if params[:locale]
    I18n.locale = params[:locale]
  end
end

然后在你的html模板中添加这一行javascript:

<html>
  <head>
    <%= stylesheet_link_tag :application, :media => :all %>
    <%= stylesheet_link_tag    "application", 'http://fonts.googleapis.com/css?family=Roboto:400,300,300italic,100,700' %>
    <%= stylesheet_link_tag    "application", 'http://fonts.googleapis.com/css?family=Roboto+Condensed:400,300,300italic' %>
    <%= javascript_include_tag :application %>
    <title>Review Blaster 9000</title>

<!-- SET LOCALE USING RAILS PARAMETER PARSING -->
    <script>I18n.locale = '<%=I18n.locale%>';</script>
<!-- END SET LOCALE -->

  </head>
  <body>

<!-- Start Ember.js -->
      <%= yield %>
<!-- End Ember.js -->

  </body>
</html>

然后在您的模板中,指定语言切换器,如下所示:

<a href='/?locale=en'>English</a>
<a href='/?locale=es'>Spanish</a>
...etc...

点击这些链接将导致应用程序的完整刷新。 Rails将解析参数,设置I18n然后Ember将以预先设置的正确值开始,因此一切都将正确绘制。