请考虑以下观点:
<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
以反射(reflect)更改。我认为使用 ko 会自动提供此功能,但也许我需要在模板的复选框数据绑定(bind)中执行某些操作?
此外,一旦我可以修改复选框并自动更新 View 模型和未读计数,那么将该更新发布回服务器(Rails)的正确方法是什么?
以下是来自服务器的 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
}]
}
最佳答案
似乎您可以在 click 上执行函数(在 data-bind='click: function() {...}'
内)对于每个项目,根据选中的复选框的值递增或递减未读计数器。这样,您就不必循环遍历 currentList
并以这种方式更新未读计数。
您还可以订阅 View 模型的 read
显式属性并在 read
时执行您自己的代码更改(请参阅 observables documentation 中间的“显式订阅可观察量”)。
编辑:Here's一个用户描述如何使用具有可观察属性的项目设置可观察数组的线程。 Here这是作者(Steve Sanderson)提出的一个示例,演示了具有可观察属性的可观察数组。
使用这两种方法,您似乎都可以执行 AJAX 调用来 POST 回服务器。
更新:以下是如何实现此功能的示例:
$(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);
});
<强> Demo here .
注释:
- 不使用 map 插件。但总体逻辑应该是相同的。
- 如果 AJAX 调用失败,您可能应该在点击之前更新复选框的状态。
- 您可以更新
unreadCount
通过调用viewModel.unreadCount(<value>)
在 viewModel 中的任何位置属性. - 这是基于几个示例,特别是 this one 。这些复杂的示例特别令人大开眼界,并展示了您可以使用 KO 做的一些很酷的事情。
关于jquery - 如何修改 JSON 中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4547316/