Knockout.js 更改不同的可观察对象时更新可观察数组属性
我有一个可以观察到的“locale”,它基本上只是一个包含特定于locale的字符串的JS对象。我还有一个tabs observable数组,它包含多个属性,其中一个属性是由区域设置值填充的标题 e、 g 下面是一个要演示的JSFIDLE: 我正试图找出最好的策略,当可观察的区域设置发生变化时,使选项卡标题发生变化Knockout.js 更改不同的可观察对象时更新可观察数组属性,knockout.js,Knockout.js,我有一个可以观察到的“locale”,它基本上只是一个包含特定于locale的字符串的JS对象。我还有一个tabs observable数组,它包含多个属性,其中一个属性是由区域设置值填充的标题 e、 g 下面是一个要演示的JSFIDLE: 我正试图找出最好的策略,当可观察的区域设置发生变化时,使选项卡标题发生变化 我尝试过使用敲除映射,但这似乎没有帮助。我还尝试添加一个ko.observearray.fn.refresh来更新选项卡数组中的数据,但它只是使用原始选项卡数据,而不是引用回区域设置
我尝试过使用敲除映射,但这似乎没有帮助。我还尝试添加一个ko.observearray.fn.refresh来更新选项卡数组中的数据,但它只是使用原始选项卡数据,而不是引用回区域设置数据。您可以使用
订阅(请参阅)来了解区域设置的值何时发生更改。看见每次更改locale
的值时,视图模型中的以下可观察订阅将触发。您可以将自己的自定义逻辑放入函数中
self.locale.subscribe(function(){
alert('locale changed');
});
这个怎么样
或者,对于rwisch45的fiddle来说,这也很有效您最好的选择是使用客户端i18n解决方案,例如。允许用户动态更改区域设置的问题在于,这将导致极其复杂的UI。否则将成为样板文件的文本(例如,字段标签、选项卡等)需要是可观察的,以便响应您的区域设置中可观察到的更改(最有可能在配置模块中)。这种可配置的可观察性必须被注入到每个模块中,以便驱动区域设置中的可观察变化
我们尝试了你正在采取的方法,发现它给我们带来了沉重的负担。我们选择了一些不引人注目的东西,一些不需要到处可见的东西,只是为了传达语言的变化
@rwisch45建议订阅,这对于一个小的解决方案来说是可行的,而且效果很好。但是订阅不会很好地扩展。在考虑了这里的答案后,特别是Chuck的答案,这是我能想到的最好的答案:
添加重新填充选项卡数组的订阅,使用键查找更改的区域设置字符串:
self.locale.subscribe(function (data) {
var newTabs = [];
ko.utils.arrayForEach(self.tabs(), function(tab) {
tab.title = data.tabs[tab.key];
newTabs.push(tab);
});
self.tabs(null);
self.tabs(newTabs);
});
不太好,我意识到我可能没有以正确的方式思考这个问题。幸运的是,大多数本地化都是在html视图中完成的,这很好。这是我需要帮助的自定义逻辑,而不是subscribe.tabs,这是一个比我在示例中指出的复杂得多的对象。它包含多个属性,其中一个是本地化标题。我的错。我不认为我可以从头开始重写它。尽管我会研究调用一个帮助函数来返回一个新的tabs对象,并根据您的第二个小提琴图使用新的本地化值。请使用敲除法查看此小提琴图中的翻译:。也许这会给你更多的想法。:-)我怀疑你的例子只是简化了你的问题:-)谢谢你的想法。locale实际上是i18next返回的一个可观察值。如图所示,它可以很好地处理数据绑定属性,但不能直接在另一个observableArray中使用。我现在也发现开销越来越大。我可以即时翻译标签和任何可观察的数组,但我还必须从服务器刷新数据,并设置和刷新任何其他组件的区域设置,例如momentjs、kendo。大多数用户实际上只会用一种语言登录,因此开销是不可接受的。@SpaceMonkey很高兴我能提供帮助。有时候你只需要沿着一条路走下去,看看它会走到哪里:)。
<ul data-bind="with: locale">
<li data-bind="text: tabs.one"></li>
<li data-bind="text: tabs.two"></li>
</ul>
self.locale.subscribe(function (data) {
var newTabs = [];
ko.utils.arrayForEach(self.tabs(), function(tab) {
tab.title = data.tabs[tab.key];
newTabs.push(tab);
});
self.tabs(null);
self.tabs(newTabs);
});