我正在为我正在处理的应用程序构建多语言支持。在做了一些研究和阅读SO(internationalization best practice)后,我试图以“框架友好”的方式将其整合。 我现在所做的是:
创建的.resource模块格式如下:
resources.en-US.js
define(function () {
return {
helloWorlLabelText: "Hello world!"
}
});
在app.start上,我获得了包含requirejs的资源模块,并将所有数据分配给app.resources。在每个模块内部,特定资源被分配给可观察对象,并通过文本绑定到标签和其他与文本相关的东西来绑定。像这样:
define(function (require) {
var app = require('durandal/app'),
router = require('durandal/plugins/router')
};
return{
helloWorldLabelText: ko.observable(app.resources.helloWorldLabelText),
canDeactivate: function () {
}
}
});
On the view:
<label for="hello-world" data-bind="text: helloWorldLabelText"></label>
只需将新模块分配给app.resources即可交换资源。
现在的问题是当语言被更改并且某些视图已经被渲染时,之前语言的值仍然存在。所以我最终在 activate 方法中重新分配了observable。还尝试将app.resources包装到observable中,但这也不起作用。
我不认为我最干净的方式,也许其他人有其他方式可以分享。感谢。
答案 0 :(得分:4)
我对这个主题的答案很有启发,所以我想出了我自己的针对Knockout / Durandal的i18n模块+绑定的实现。
另一个i18n模块的选择是我更喜欢将翻译存储在数据库(每个项目所需的类型)而不是文件中。使用该实现,您只需要一个后端,该后端必须以键值方式回复包含所有翻译的JSON对象。
@RainerAtSpirit 单例类的好提示对模块非常有帮助
答案 1 :(得分:3)
您可以考虑使用一个i18n
模块返回包含所有必需可观察对象的单例。另外还有一个init函数,它接受一个i18n对象来初始化/更新它们。
define(function (require) {
var app = require('durandal/app'),
i18n = require('i18n'),
router = require('durandal/plugins/router')
};
return{
canDeactivate: function () {
}
}
});
On the view:
<label for="hello-world" data-bind="text: i18n.helloWorldLabelText"></label>
答案 2 :(得分:3)
以下是使用i18next,Knockout.Punches和Knockout 3与Durandal进行的回购示例:
https://github.com/bestguy/knockout3-durandal-i18n
这允许通过由i18next支持的i18n
文本过滤器来处理本地化文本的Handlebars / Angular风格:
<p>
{{ 'home.label' | i18n }}
</p>
还支持属性嵌入:
<h2 title="{{ 'home.title' | i18n }}">
{{ 'home.label' | i18n }}
</h2>
还允许您传递参数:
<h2>
{{ 'home.welcome' | i18n:name }}
<!-- Passing the 'name' observable, will be embedded in text string -->
</h2>
JSON示例:
英语(en):
{
"home": {
"label": "Home Page",
"title": "Type your name…"
"welcome": "Hello {{0}}!",
}
}
中文(zh):
{
"home": {
"label": "家",
"title": "输入你的名字……",
"welcome": "{{0}}您好!",
}
}