之前我问过这个问题,但没有得到太多回应。很明显,我不太清楚我想要实现的目标,所以我会再试一次。
我正在开发一个应用程序,它将(以一定间隔)调用一个Web方法,该方法将读取数据库并构建一个返回的JSON字符串,用于构建我的视图模型。当我的视图模型发生变化时,我需要使用新数据改变所有选定的observable。
以此为基础模型示例。
var model = {
people: [
{ forename: "Test", surname: "Person", numbers: [1,2,3] },
{ forename: "Another", surname: "Test", numbers: [4,5,6] }
]
};
很简单,一个人的表格会弹出一个模态时会弹出一个列表,显示所选人员的numbers
列表。虽然这个模态是开放的,但数据可能会在幕后更新,所以如果选择了[测试人员](弹出模态),某人在某处将[7,8,9]
添加到他们的numbers
,那么我需要要刷新的模态显示这些添加。
这是一个基本的视图模型(为简洁起见使用ko.mapping
):
var viewModel = {
people: ko.mapping.fromJS(model.people),
selectedPerson: ko.observable(null),
refresh: function () {
ko.utils.arrayForEach(model.people, function (person) {
var last = person.numbers[person.numbers.length - 1];
var newNumber = last + 1;
person.numbers.push(newNumber);
});
ko.mapping.fromJS(model.people, this.people);
console.log(ko.toJSON(this));
}
};
当点击一行时,该人存储在selectedPerson
中,这使我的模态在UI中可见(我正在使用Zurb Foundation):
<div id="modal" class="reveal-modal" data-bind="if: selectedPerson">
此模式显示一个numbers
表,其中包含一个名为Update Observable的按钮 - 这会调用一个函数来模拟对基础模型的更改(在这种情况下,我将采用numbers
中的最后一项将其递增1并将其推上)。完成后我再重新创建我的视图模型(为了简洁起见使用ko.mapping
)并期望更新UI上的所有内容以反映更改 - 除了模态之外都很好。
在重新映射后查看我的视图模型的JSON,我可以看到视图模型已正确更新,但selectedPerson
没有。我认为selectedPerson
是一个参考,而不是副本,但我显然错了,我们最终得到了这个。
{
"people": [
{
"forename": "Test",
"surname": "Person",
"numbers": [1,2,3,4,5,6,7,8]
},
{
"forename": "Another",
"surname": "Test",
"numbers": [4,5,6,7,8,9,10,11]
}
],
"selectedPerson": {
"forename": "Test",
"surname": "Person",
"numbers": [1,2,3]
}
}
所以我想我的问题是:当基础模型发生变化时,如何更新selectedPerson
(或实际上可能存在的任何其他选定的可观察量)?
答案 0 :(得分:1)
您的问题是ko.mapping.fromJS(model.people, this.people)
清空并重新创建您的people
集合。但是您的selectedPerson
仍然引用了旧person
对象之一。
您需要告诉映射插件如何识别您的项目,以便更新它们:
ko.mapping.fromJS(model.people,
{ key: function(item) { return item.forename; } },
this.people);
演示JSFiddle。
或者作为替代解决方案,您可以在映射后将selectedPerson
重置为新创建的person
对象之一:
this.selectedPerson(ko.utils.arrayFirst(this.people(), function(item){
return item.forename() == this.selectedPerson().forename();
}, this));
演示JSFiddle。