我有一个模态表单,其中两个嵌套列表绑定到可观察数组。
每次单击按钮打开模态时,这两个嵌套列表都不会清除以前的数据,即使我为整个事物生成了一个全新的视图模型。我最终会在这两个列表中找到重复的(和三重的......等)项目。
如何确保在为此事物提供新视图模型时,它会清除以前的数据?
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>
这是我的“基础”VM:
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();
}
});
答案 0 :(得分:4)
由于您自己想出了处理此问题的最佳方式(使用模板),但您表示您想知道发生了什么:
引擎盖foreach
foreach
就像就地模板绑定一样。与innerHTML
绑定的元素的foreach
被视为模板字符串。
当你cleanNode
时,淘汰不会&#34;撤消&#34;它的绑定;它只删除view(HTML)和viewmodel(js)之间的依赖关系。绑定上下文已删除。
这意味着,在cleanNode
之后,用作模板的内部HTML会发生变化。
cleanNode
&#13;
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"));
&#13;
按按钮应用装订并在之后清洁。控制台记录使用的模板。第一次运行时,模板包含一个 <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>
,重复三次次。第二次运行时,模板包含三个 <li>
元素,这些元素重复三次。 I.e。:列表项的数量等于<li>
的{{1}}。
3^n
绑定模板绑定并不关心数据绑定元素中的内容。它只是丢弃所有n = numer of times bindings are applied
并将其替换为链接的模板。
再次,就像评论者所说的那样,你永远不需要拨打template
(可能是自定义绑定之外)。
答案 1 :(得分:0)
我能够使用淘汰赛template binding完成所需的行为:
<div class="notes-container" data-bind="visible: showNotesContainer">
<label>Notes</label>
<ul class="question-list" data-bind="template: { name: 'hours-noteGroups-template', foreach: noteGroups }"></ul>
<script type="text/html" id="hours-noteGroups-template">
<li><span class="he-question-group" data-bind="text: name"></span>
<ul id="he-notes-list" 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>
</script>
</div>
我仍然很想知道为什么最初的尝试按照它的方式行事。