题
请考虑以下视图:
<p>Count <span data-bind="text: unreadCount()"> </span></p>
<div data-bind='template: { name: "conversationTemplate", data: currentList }'> </div>
<script type="text/html" id="conversationTemplate">
<table>
<tbody>
{{each $data}}
<tr id="conversation_${conversation_id}" class="conversation-item ${status}">
<td><input type="checkbox" data-bind="click: function() { alert(this.value) }, checked: read" /></td>
</tr>
{{/each}}
</tbody>
</table>
</script>
以及以下代码:
$(function() {
var viewModel = {
currentList : ko.observableArray([])
};
ko.dependentObservable(function () {
$.ajax({
url: '/conversations/inbox.json', dataType: 'json',
success: function(data) {
viewModel.currentList(data.conversationlist);
}
});
}.bind(viewModel));
viewModel.unreadCount = ko.dependentObservable(function() {
var unreadCount = 0;
for (var i = 0; i < viewModel.currentList().length; i++)
if (viewModel.currentList()[i].read == true) {
unreadCount++;
}
return unreadCount;
});
ko.applyBindings(viewModel);
以上似乎在起作用,尽管我不确定是否正确构建了它。我想学习的方法是改变 复选框, ,如何拥有 unreadCount
自动更新以反映更改。我认为使用KO会自动提供此功能,但是也许我需要在模板的复选框数据绑定中做一些事情?
另外,一旦我可以修改复选框并使该复选框自动更新视图模型和未阅读计数,那么将该更新发布回服务器(RAIRS)的正确方法是什么?
这是服务器的JSON响应示例:
{
"conversationlist": [{
"project_name": "Proj 1",
"preview": "xxxxx",
"status": "unread",
"participants": [{
"image": "XXXXXX"
}, {
"image": "XXXXXX"
}],
"conversation_id": 193,
"title": "Hi Ho",
"time_ago": "1 day",
"read": true
}, {
"project_name": "Proj 2",
"preview": "xxxx",
"status": "unread",
"participants": [{
"image": "XXXXXX"
}, {
"image": "XXXXXX"
}],
"conversation_id": 193,
"title": "Hi Ho",
"time_ago": "1 day",
"read": true
}, {
"project_name": "Proj 3",
"preview": "xxxxx",
"status": "unread",
"participants": [{
"image": "XXXXXX"
}, {
"image": "XXXXXX"
}],
"conversation_id": 193,
"title": "Hi Ho",
"time_ago": "1 day",
"read": true
}]
}
解决方案
似乎您可以在 点击 (里面 data-bind='click: function() {...}'
)对于每个项目,取决于所检查的复选框的值。这样,您永远不必循环 currentList
并以这种方式更新未读的计数。
您也可以订阅ViewModel的 read
属性明确并执行您自己的代码 read
更改(请参阅“明确订阅可观察物”的中间 观察文档).
编辑: 这是 一个用户描述他们如何设置具有可观察属性的项目的线程。 这里作者(史蒂夫·桑德森(Steve Sanderson))提出了一个可观察到的属性的示例。
使用这两种方法,您似乎可以执行AJAX调用以将其发布回服务器。
更新: :这是您如何实现此目的的一个示例:
$(function() {
var initialData = {/*Data retrieved by AJAX or on page load*/};
var markRead = function(conversation) {
// Make AJAX POST here to update read status of
// the conversation
};
// Convenience object for conversations.
var Conversation = function(conversation_id, status, read) {
this.conversation_id = conversation_id;
this.status = status;
this.read = ko.observable(read);
};
var initialUnread = 0;
var viewModel = {
// Map the conversation list to a new array containing
// objects with observable properties.
conversationList: ko.observableArray(ko.utils.arrayMap(
initialData.conversationlist, function(data) {
if (!data.read === false) {
initialUnread++;
}
return new Conversation(
data.conversation_id,
data.status,
data.read);
})),
unreadCount: ko.observable(initialUnread),
// Executed when the user toggles a conversation's
// read status.
toggleRead: function(conversation) {
// Update the unread count.
viewModel.unreadCount(
viewModel.unreadCount() +
(conversation.read() ? 1 : -1));
// Update the conversation via AJAX
markRead(conversation);
return true;
}
};
ko.applyBindings(viewModel);
});
笔记:
- 不使用映射插件。一般逻辑应该相同。
- 如果AJAX调用失败,则可能应该在单击之前更新其状态的复选框。
- 您可以更新
unreadCount
通过调用ViewModel中的属性viewModel.unreadCount(<value>)
. - 这是基于几个示例,特别是 这个. 。复杂的例子特别令人大开眼界,并展示了您可以使用KO做的一些很酷的事情。
不隶属于 StackOverflow