Knockout 映射插件文档有一个标题为“使用“键”唯一标识对象”的部分。这描述了如何更新对象的一部分,然后仅更新显示的该部分,而不是完全替换部分修改对象的所有属性的显示。在他们的简单示例中,这一切都非常出色,我在这里对其进行了轻微修改,以使我的问题更清楚。我的修改是:
延迟 2 秒后用更正的名称替换对象。
突出显示显示中不变的部分,这样您就可以看到更新发生时它实际上没有被替换。
1. 简单对象(jsFiddle)
<h1 data-bind="text: name"></h1>
<ul data-bind="foreach: children">
<li><span class="id" data-bind="text: id"></span> <span data-bind="text: name"></span></li>
</ul>
<script>
var data = {
name: 'Scot',
children: [
{id : 1, name : 'Alicw'}
]
};
var mapping = {
children: {
key: function(data) {
console.log(data);
return ko.utils.unwrapObservable(data.id);
}
}
};
var viewModel = ko.mapping.fromJS(data, mapping);
ko.applyBindings(viewModel);
var range = document.createRange();
range.selectNode(document.getElementsByClassName("id")[0]);
window.getSelection().addRange(range);
setTimeout(function () {
var data = {
name: 'Scott',
children: [
{id : 1, name : 'Alice'}
]
};
ko.mapping.fromJS(data, viewModel);
}, 2000);
</script>
但我不清楚的是如何为更复杂的嵌套数据结构实现相同的行为。在下面的示例中,我采用了上面的代码并将数据包装在一个列表中。我希望它的行为与上述相同,但事实并非如此。由于一个属性的变化,整个显示被重做。您可以看到这一点,因为与上面的示例不同,数据更新后突出显示会丢失。
2.更复杂的嵌套对象(jsFiddle)
<!-- ko foreach: parents -->
<h1 data-bind="text: name"></h1>
<ul data-bind="foreach: children">
<li><span class="id" data-bind="text: id"></span> <span data-bind="text: name"></span></li>
</ul>
<!-- /ko -->
<script>
var data = {
parents: [
{
name: 'Scot',
children: [
{id : 1, name : 'Alicw'}
]
}
]
};
var mapping = {
children: {
key: function(data) {
console.log(data);
return ko.utils.unwrapObservable(data.id);
}
}
};
var viewModel = ko.mapping.fromJS(data, mapping);
ko.applyBindings(viewModel);
var range = document.createRange();
range.selectNode(document.getElementsByClassName("id")[0]);
window.getSelection().addRange(range);
setTimeout(function () {
var data = {
parents: [
{
name: 'Scott',
children: [
{id : 1, name : 'Alice'}
]
}
]
};
ko.mapping.fromJS(data, viewModel);
}, 2000);
</script>
所以基本上我要问的是,考虑到更多嵌套的数据结构,我怎样才能让第二个例子像第一个例子一样工作?您可以假设每个孩子的 id 都是唯一的(因此,如果我在 Scott 之外添加另一个父母,他的孩子将以 id=2 开头,等等)。