我有一个模态形式,其中有两个绑定到可观察数组的嵌套列表。
每次我单击按钮打开模式时,这两个嵌套列表都不会清除它们以前的数据,即使我为整个事物生成了一个全新的视图模型。我最终在这两个列表中得到了重复的(和三次的,等等)项目。
如何确保当我给这个东西一个新的视图模型时,它会清除以前的数据?
ViewModel 本身很好:我可以ko.toJS(self)
在每个实例上,数据中的所有内容都是正确的。这是绑定的某种剩余物。
这是我对该特定区域的绑定:
<div class="notes-container" data-bind="visible: showNotesContainer">
<label>Notes</label>
<ul data-bind="foreach: noteGroups" class="question-list">
<li>
<span class="he-question-group" data-bind="text: name"></span>
<ul class="he-question-list" data-bind="foreach: notes">
<li><span data-bind="text: question"></span></li>
<li><input type="text" data-bind="value: answer" /></li>
</ul>
</li>
</ul>
</div>
这是我的“基础”虚拟机:
function hoursEntryVM(model) {
var self = this;
...
self.noteGroups = ko.observableArray(getNoteGroupsVMs(model.NoteGroups));
...
var root = document.getElementById(model.rootElementId);
ko.cleanNode(root)
ko.applyBindings(self, root);
return self;
function getNoteGroupsVMs(noteGroupModel) {
var notes = [];
for (var i = 0; i < noteGroupModel.length; i++) {
notes.push(new hoursNoteGroupVM(noteGroupModel[i]));
}
return notes;
}
}
在按钮上单击打开模式我有这样的东西:
$.ajax({
url: '/mysource',
success: function(data) {
data.rootElementId = 'hours-entry-container';
var vm = new window.myProj.hoursEntry.hoursEntryVM(data);
console.log(ko.toJS(vm));
myModal.Show();
}
});
既然您自己找到了处理此问题的最佳方法(使用模板),但您表示您想知道发生了什么:
foreach
在引擎盖下
foreach
工作原理类似于就地模板绑定。这innerHTML
与 绑定的元素foreach
被视为模板字符串。
What cleanNode
does not do
当你cleanNode
,敲除不会“撤销”其绑定;它仅删除视图(HTML)和视图模型(js)之间的依赖关系。绑定上下文被删除。
这意味着,之后cleanNode
,用作模板的内部 HTML 发生变化。
演示:
var source = [1, 2, 3];
var applyAndClean = function() {
var el = document.querySelector("ul");
console.log("Applying bindings using template:");
console.log(el.innerHTML);
ko.applyBindings(source, el);
ko.cleanNode(el);
}
ko.applyBindings({
onClick: applyAndClean
}, document.querySelector("button"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<button data-bind="click: onClick">apply and clean</button>
<ul data-bind="foreach: $data">
<li data-bind="text: $data"></li>
</ul>
按下按钮应用固定器并随后进行清洁。控制台记录所使用的模板。第一次运行,模板包含one <li>
不断重复three次。第二次运行,模板包含three <li>
重复三次的元素。即:列表项的数量等于3^n
for n = numer of times bindings are applied
.
与的区别template
binding
模板绑定不关心数据绑定元素中的内容。它只是丢弃所有innerHTML
并将其替换为链接的模板。
再次,就像评论者所说,你永远不需要打电话cleanNode
(也许在自定义绑定之外)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)