Please consider the following view:
<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>
And the following code:
$(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);
The above appears to be working, though I’m not sure if I built this correctly. What I want to learn how to do is when you change a checkbox, how to have the unreadCount be automatically updated to reflect the change. I thought that using ko would provide this automatically, but maybe I need to do something in the template’s checkbox data-bind?
Also, once I can modify the checkbox and have that automatically update the View Model & Unread count, what is the right way to then post that update back to the server (Rails)?
Here’s an example JSON response from server:
{
"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
}]
}
Seems like you could execute a function on click (inside
data-bind='click: function() {...}') for each item that increments or decrements the unread counter depending on the value of the checkbox that was checked. This way, you wouldn’t ever have to loop through thecurrentListand update the unread count that way.You could also subscribe to the viewmodel’s
readproperty explicitly and execute your own code whenreadchanges (see “Explicitly subscribing to observables” in the middle of the observables documentation).Edit: Here’s a thread where one user describes how they set up an observable array with items with observable properties. Here‘s an example that the author (Steve Sanderson) came up with demonstrating an observable arrays with observable properties.
With both methods, it seems like you could perform an AJAX call to POST back to the server.
Update: Here’s an example of how you could implement this:
Demo here.
Notes:
unreadCountproperty in the viewModel anywhere by callingviewModel.unreadCount(<value>).