14

我正在使用 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(path) 左右的东西)?

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

  4. 当您离开模板然后重新输入模板时,模板本身会使用所有语言字符串重建,还是仅在同时更改语言时才会出现这种预期行为?如何在控制台日志中跟踪这种带有新字符串的模板重建?

有什么其他想法可以使它成为一个强大的交换解决方案吗?

4

3 回答 3

0

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

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');
    };
}
于 2014-10-09T12:26:28.980 回答
0

我尝试了这里列出的所有方法,但都遇到了各种问题。我发现了一个更优雅的技巧来完成这项工作。

警告:这仅在您使用 Rails 为 Ember 提供服务时才有效(但可能适用于任何服务器端框架)。

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

我发现最好的方法是在 Ember 加载之前使用 Rails 上设置的参数指定语言环境。

导轨配置:

使您的 ember#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 将从预先设置的正确值开始,所以一切都会正确绘制。

于 2014-11-30T18:05:55.270 回答
0

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

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

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

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

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

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

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

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

于 2013-12-09T14:06:34.600 回答