更新
我原来的帖子很长 - 这是 tl;dr 版本:
在单个属性更改后如何更新剔除模型的所有属性?更新函数必须引用 viewModel 中的 observableArray。
- 更多细节 -
我正在使用 KnockoutJS。我在视图模型中有一个 Zoo 和一个 Tapir 模型以及三个 observables - zoos、tapirCatalog 和 currentTapir。tapirCatalog 是从服务器填充的,currentTapir 保存当时正在编辑的任何 tapir 的值。
这就是我想要完成的事情:用户已将貘列表中的貘添加到他/她的动物园。在查看动物园时,用户可以编辑貘并将其替换为另一只貘。为此,将显示一个弹出窗口,其中包含一个由貘名称填充的选择表单和一个显示当前选定的 GoofinessLevel 的跨度。
So, when the select element changes this changes the TapirId in currentTapir. 我希望它触发一些改变 currentTapir 的 Name 和 GoofinessLevel 的东西。
我尝试订阅 currentTapir().GoofinessLevel 但无法触发:
function Zoo(data) {
this.ZooId = ko.observable(data.ZooId);
this.Tapirs = ko.observableArray(data.Tapirs);
}
function Tapir(data) {
this.TapirId = ko.observable(data.TapirId);
this.Name = ko.observable(data.Name);
this.GoofinessLevel = ko.observable(data.Name);
}
function ViewModel() {
var self = this;
// Initializer, because I get an UncaughtType error because TapirId is undefined when attempting to subscribe to it
var tapirInitializer = { TapirId: 0, Name: "Template", GoofinessLevel: 0 }
self.zoos = ko.observableArray([]);
self.tapirCatalog = ko.observableArray([]);
self.currentTapir = ko.observable(new Tapir(tapirInitializer));
self.currentTapir().TapirId.subscribe(function (newValue) {
console.log("TapirId changed to: " + newValue);
}); // This does not show in console when select element is changed
};
奇怪的是,当我订阅 Tapir 模型中的 Goofiness 级别时,我得到了触发器:
function Tapir(data) {
var self = this;
self.TapirId = ko.observable(data.TapirId);
self.Name = ko.observable(data.Name);
self.GoofinessLevel = ko.observable(data.Name);
self.TapirId.subscribe(function (newId) {
console.log("new TapirId from internal: " + newId);
}); // This shows up in the console when select element is changed
}
我怀疑这对于使用 KO 的人来说是很常见的情况,但我找不到任何东西。而且我已经搜索了一段时间(可能我没有正确的词汇来搜索?)。我确实找到了这个解决方案,但他从模型本身引用了视图模型——这似乎是回编码,因为我认为貘不应该对动物园有任何了解:http: //jsfiddle.net/rniemeyer/QREf3/
** 更新 ** 这是我的选择元素的代码(父 div 有data-bind="with: currentTapir"
:
<select
data-bind="attr: { id: 'tapirName', name: 'TapirId' },
options: $root.tapirCatalog,
optionsText: 'Name',
optionsValue: 'TapirId',
value: TapirId">
</select>