我有一个很大的viewModel,我想将状态更新(“read”/“unread”)发布到服务器而不发布整个模型。
我所做的是创建一个自定义绑定,如下所示:
ko.bindingHandlers.statusUpdater = {
update: function(element, valueAccessor) {
console.log(element);
}
};
在模板中:
<div data-bind='template: { name: "contactsListTemplate", data: viewModel.conversations.conversationlist }'> </div>
<script type="text/html" id="contactsListTemplate">
<table>
<tbody>
{{each(i, conversation) $data}}
<tr>
<td>
<input type="checkbox" data-bind="checked: read, statusUpdater: conversation_id" />
</td>
</tr>
{{/each}}
</tbody>
</table>
</script>
对于自定义绑定,我只对Updates感兴趣,我认为允许我做的是使用KnockoutJS检测更新,并确定哪个项目已更新,以便我可以获取该项ID和新统计信息,然后将其发布到服务器。
正在发生的事情是customBinding是console.log
ging单个复选框修改的每个复选框。这意味着我更改了一个复选框,所有3个复选框都通过ko.bindingHandlers.statusUpdater
登录到控制台。
我考虑过将click事件添加到数据绑定中,但这似乎不像自定义绑定那样干净。或许我想用自定义绑定做的不是他们的目的吗?
思想?
答案 0 :(得分:4)
这样做的原因是因为每次更新模型值时都会调用update方法,并且在调用init方法后的开始时调用。
更新绑定方法用于在viewmodel更改时设置绑定dom元素的状态。
如果您想对更改做出反应并更新viewModel,则需要实现init方法并附加事件(单击,更改等)。在此处理程序中,您可以将状态更新发送到您的viewmodel。
ko.bindingHandlers.statusUpdater = {
'init': function (element, valueAccessor, allBindingsAccessor) {
var updateHandler = function() {
var valueToWrite;
if (element.type == "checkbox") {
valueToWrite = element.checked;
} else if ((element.type == "radio") && (element.checked)) {
valueToWrite = element.value;
} else {
return; // "checked" binding only responds to checkboxes and selected radio buttons
}
var modelValue = valueAccessor();
if (ko.isWriteableObservable(modelValue)) {
if (modelValue() !== valueToWrite) { // Suppress repeated events when there's nothing new to notify (some browsers raise them)
$.ajax({
url: 'someurl',
success: function(data) {
alert('status update');
}
});
modelValue(valueToWrite);
}
} else {
var allBindings = allBindingsAccessor();
if (allBindings['_ko_property_writers'] && allBindings['_ko_property_writers']['checked']) {
allBindings['_ko_property_writers']['checked'](valueToWrite);
}
}
};
$(element).click(updateHandler).change(updateHandler);
},
'update': function (element, valueAccessor) {
ko.bindingHandlers.checked(element, valueAccessor);
}
};
我发现学习这个的最好方法是在git上查看KO的调试版本。你想要实现的基本上是一个带有ajax调用的修改的检查绑定。
我没有对上述内容进行测试,但它应该让你开始。
干杯,
伊恩