如何停止Knockout清除复选框?
https://jsfiddle.net/mezv2tns/
var vm = {
state: ko.observable({
'success': true,
'items': [{'name': 'abc'}, {'name': 'def'}]
}),
items: ko.observableArray([{'name': 'abc'}, {'name': 'def'}]),
itemsMapping: ko.observableArray([{'name': 'abc'}, {'name': 'def'}]),
};
$(function() {
console.log('go');
ko.applyBindings(vm, $('#a')[0]);
setInterval(function() {
console.log('update');
// Imagine this is coming from an Ajax request.
var dataFromServer = [{'name': 'abc'}, {'name': 'def'}, {'name': 'new'}];
var stateFromServer = {'success': true, 'items': dataFromServer};
// Update the observables using different techniques.
vm.state(stateFromServer);
vm.items(dataFromServer);
ko.mapping.fromJS(dataFromServer, {}, vm.itemsMapping);
}, 1000);
});
HTML:
<table data-bind="foreach: state().items">
<tr><td><input type="checkbox"></td><td><span data-bind="text: name"></span></td></tr>
</table>
我希望服务器不断更新以更新表,但复选框应该独立于此;我不想将复选框状态发送到服务器,然后将其与更新合并。
答案 0 :(得分:1)
复选框未被清除,它们正在重新绘制。您可以使用foreach
绑定根据observableArrays中的内容生成它们。每个“服务器提取”都会替换数组中的数据,因此您将获得新的框。
如果您希望绘制的项目持续存在,则除了丢弃和替换所有数据之外,您还必须执行其他操作。例如,当新数据进入时,您只删除不再表示的项目,并添加任何新项目。
var initialData = [{'name': 'abc'}, {'name': 'def'}];
var vm = {
state: ko.observable({
'success': true,
'items': initialData
}),
items: ko.observableArray(initialData),
itemsMapping: ko.observableArray(initialData),
persistentItems: ko.observableArray(initialData)
};
function updatePersistent(newData) {
// Delete any that are not in newData (not implemented)
// Add any that are not already here
for (var i=0; i<newData.length; ++i) {
if (!found(newData[i])) vm.persistentItems.push(newData[i]);
}
}
function found(item) {
var items = vm.persistentItems();
for (var i=0; i<items.length; ++i) {
if (items[i].name == item.name) return true;
}
return false;
}
$(function() {
console.log('go');
ko.applyBindings(vm, $('#a')[0]);
setInterval(function() {
console.log('update');
// Imagine this is coming from an Ajax request.
var dataFromServer = [{'name': 'abc'}, {'name': 'def'}, {'name': 'new'}];
var stateFromServer = {'success': true, 'items': dataFromServer};
// Update the observables using different techniques.
vm.state(stateFromServer);
vm.items(dataFromServer);
ko.mapping.fromJS(dataFromServer, {}, vm.itemsMapping);
updatePersistent(dataFromServer);
}, 1000);
});
div div {
border: 1px solid black;
text-align: center;
margin: 1px;
height: 50px;
}
h1 {
font-size: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<div id="a">
<h1>Desired Technique</h1>
<table data-bind="foreach: state().items">
<tr><td><input type="checkbox"></td><td><span data-bind="text: name"></span></td></tr>
</table>
<hr>
<h1>Technique 2</h1>
<table data-bind="foreach: items()">
<tr><td><input type="checkbox"></td><td><span data-bind="text: name"></span></td></tr>
</table>
<hr>
<h1>Technique 3</h1>
<table data-bind="foreach: itemsMapping()">
<tr><td><input type="checkbox"></td><td><span data-bind="text: name"></span></td></tr>
</table>
<h1>Persistent</h1>
<table data-bind="foreach: persistentItems">
<tr><td><input type="checkbox"></td><td><span data-bind="text: name"></span></td></tr>
</table>
</div>