如何在i18next中使用Knockout observable?

我试图以某种方式动态地使用i18next翻译和Knockout.js,但我无法弄清楚如何。

自定义Knockout绑定或i18next jQuery插件似乎都不适用于可观察值。

我可以在这里找到我想要实现的演示: http : //jsfiddle.net/rdfx2/1/

解决方法是这样的,但我宁愿避免这种情况,如果可能的话:

self.translate = function (key, value) { return i18next.t(key, { "var": value }); };

谢谢,

我对i18next不是很熟悉,所以我可能错误地使用了i18next,但你可以通过创建一个bindingHandler轻松实现这一点。 这种bindingHandler的一个非常简单的版本,支持传递可选选项,看起来像:

 ko.bindingHandlers['translatedText'] = { update: function(element, valueAccessor, allBindings){ var key = ko.unwrap(valueAccessor()); var options = ko.toJS(allBindings.get('translationOptions') || {}); var translation = i18n.t(key, options); element.innerText = translation; } }; 

给出以下i18next初始化代码:

 i18n.init({ lng: "en", debug: true, resStore: { en: { translation: { 'myTextKey': 'My translated value is "__value__"', 'otherTextKey': 'This is just a text which does not use options' } } } }); 

您可以将它与以下HTML一起使用:

  

以下视图模型:

 function ViewModel(){ this.input = ko.observable(); } ko.applyBindings(new ViewModel); 

我已将上述代码保存到jsfiddle,您可以在http://jsfiddle.net/md2Hr/找到

我已经更新了代码以支持翻译HTML属性。

这是一个工作演示: http : //jsfiddle.net/remisture/GxEGe/

HTML

     

JS

 define(['knockout', 'i18next'], function (ko, i18n) { ko.bindingHandlers.i18n = { update: function (element, valueAccessor, allBindings) { var key = ko.unwrap(valueAccessor()), options = ko.toJS(allBindings.get('i18n-options') || {}), translation, parts, attr; // Check whether we are dealing with attributes if (key.indexOf('[') === 0) { parts = key.split(']'); key = parts[1]; attr = parts[0].substr(1, parts[0].length - 1); } translation = i18n.t(key, options); if (attr === undefined) { // Check whether the translation contains markup if (translation.match(/<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/)) { //noinspection InnerHTMLJS element.innerHTML = translation; } else { // Check whether the translation contains HTML entities if (translation.match(/&(?:[az]+|#x?\d+);/gi)) { //noinspection InnerHTMLJS element.innerHTML = translation; } else { // Treat translation as plain text element.innerText = translation; } } } else { // Add translation to given attribute element.setAttribute(attr, translation); } } }; }); 

KO配置:

 var language = ko.observable(''); ko.i18n = function(key) { return ko.computed(function() { if (language() != null) { return i18n.t(key, { lng : language() }); } else { return ""; } }, key); }; 

视图模型:

 var labels = { aboutUs: ko.i18n('app:labels.aboutUs'), contactUsBtn: ko.i18n('app:labels.contactUsBtn') } 

视图:

  

感谢一个很好的例子,@ robert.westerlund!

我稍微修改了你的例子以更好地满足我的需求:

 ko.bindingHandlers['i18n'] = { update: function (element, valueAccessor, allBindings) { var key = ko.unwrap(valueAccessor()), options = ko.toJS(allBindings.get('i18n-options') || {}), translation = i18next.t(key, options); // Check whether the translation contains markup if (translation.match(/<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/)) { element.innerHTML = translation; } else { // Check whether the translation contains HTML entities if (translation.match(/&(?:[az]+|#x?\d+);/gi)) { element.innerHTML = translation; } else { // Treat translation as plain text element.innerText = translation; } } } };