这是带有data-bind元素的html:
div data-bind="foreach: clientRequests" id="test2">
<div class="list-group" >
<a href="#" class="list-group-item active"><b data-bind="text: client"></b></a>
<a href="#" class="list-group-item"><b>Priority: </b><b data-bind="text: client_priority"></b></a>
<a href="#" class="list-group-item"><b>Title: </b><b data-bind="text: title"></b></a>
<a href="#" class="list-group-item"><b>Description: </b><b data-bind="text: description"></b></a>
<a href="#" class="list-group-item"><b>Product Area: </b><b data-bind="text: product_area"></b></a>
<a href="#" class="list-group-item"><b>Target Date: </b><b data-bind="text: target_date"></b></a>
<a href="#" class="list-group-item"><b>Ticket URL: </b><b data-bind="text: ticket_url"></b></a>
</div>
</div>
这就是我将一个名为requestsArray
的数组传递给foreach
循环的方法:
ko.cleanNode(document.getElementById('test2'));
ko.applyBindings({
clientRequests: requestsArray
}, document.getElementById('test2'));
通过各种AJAX调用,返回不同的requestArrays。例如,在初始页面加载之后,进行AJAX调用,该调用接收requestArray的一个实例,该实例可能有10个项目。 foreach循环似乎按预期运行,并且数组中的所有10个项目都填充在页面上。然后,进行第二次AJAX调用,但这次数组可能只有5个项目。会发生的是每个项目重复两次,页面上总共出现10个项目。
问题似乎是,即使之前调用了ko.cleanNode(document.getElementById('test2'))
:
ko.applyBindings({
clientRequests: requestsArray
}, document.getElementById('test2'))
对于每个新数组,每个foreach
迭代创建的HTML元素数量随着每个新数组的不断增加而不断增加。使用Vue.js,每次将新数组传递给数据绑定和for循环时,它本质上都是破坏性的,并且不会保留上一次迭代在数组上的任何内容。
显然在这种情况下使用ko.cleanNode
并不起作用,我知道in the docs有一个例子可以做我认为正确的过程,但一次只能做一个html元素通过一个按钮和self.array.remove(this)
,我不太确定如何调整它以完全清除从数组foreach
迭代创建的所有html元素。
答案 0 :(得分:1)
我不明白为什么您必须手动重新应用绑定。具有可观察数组的视图模型的重点是,淘汰赛会为您处理数据更新...通常,当您使用cleanNode
时,有一个更简单的方法的东西。
你尝试过这样的事吗?
// Apply bindings _once_, viewmodel instance does not change
// in between requests
ko.applyBindings(new ViewModel());
function ViewModel() {
// Because the array is observable, knockout will
// monitor for changes and update the UI
this.requests = ko.observableArray([]);
// The view model has the request method
// the .done callback writes the results to the observable
// requests array
this.doRequest = function() {
mockupAjaxGetter().done(this.requests);
}.bind(this);
// Do an initial request
this.doRequest();
};
// Mockup code, just to produce some random numbers on a timeout
function mockupAjaxGetter() {
var randomResults = [];
for (var i = 0; i < Math.random() * 20; i += 1) {
randomResults.push(Math.random());
}
var cb;
var applyCb = function() {
if (cb) cb(randomResults);
}
setTimeout(applyCb, 500);
return {
done: function(fn) { cb = fn; }
}
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: requests">
<li data-bind="text: $data"></li>
</ul>
<button data-bind="click: doRequest">New request</button>
&#13;