2013-08-05 43 views
13

我使用了我的整个应用程序中使用的静态字符串翻译余烬,国际化库。由于语言文件相当大,我不想在应用程序启动时加载所有可能的语言字典。因此,我想在用户选择更改语言时动态加载字典。我做了第一个实施,效果很好。烬:动态切换到所选择的语言(使用国际化库)

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. 我还想翻译字符串“外面”红格(应用插座)。我转换回索引,但在这种情况下,应用程序模板不会重新绘制...可能是什么原因?

  4. 预期的行为是,当您离开模板然后重新输入模板时,模板本身是使用所有语言字符串重建的,还是仅在此期间语言被更改时才这样做?在控制台日志中如何重新编译带有新字符串的模板?

任何其他的想法,使这一强大的开关解决方案?

回答

0

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

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

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

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

还装载subroute模型时,你已经知道langugage是什么,你可以获取当前语言(例如想想博客贴子,在每一种语言不同)的模型。使用this.modelFor('language')在任何子路径中获取当前语言。

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

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

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

+0

好的建议。我将分析将语言定义为顶级路线的影响。不太确定,这不会在别处造成一些摩擦...... – cyclomarc

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

我尝试了这里列出的所有方法,并且对所有这些方面都有各种问题。我发现了一个更加优雅的黑客来完成这项工作。

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

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

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

钢轨配置:

让你的余烬#指数控制器操作是这样的:

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将以预先设置的正确值开始,因此所有内容都将正确绘制。