I try to bind observableArray to div on my page and everything is ok. This array contains simple JSON objects, not observable, obtained from WebService.
After that, I want to be able to modify those objects in array and would like view to be refreshed with each modification. For example, when checkbox gets clicked I would like to change the flag on my JSON object (this seems to work automatically all right) and at the same time my UI should get updated, which does not happen. Could anyone provide me with the reason (is this because those objects are simple, not observable?) and solution?
var DocumentContentModel = function () {
var self = this;
self.content = ko.observableArray();
self.ElementApprovalChanged = function (element) {
DocumentService.DoSomething(
element.Id,
function (result) {
if (!result) {
var negatedApproved = !element.Approved;
element.Approved = negatedApproved;
}
},
function (error) {
alert(error);
});
return true;
};
};
$(document).ready(function () {
var contentModel = new ContentModel();
DocumentService.GetContent(1,
function (result) {
contentModel.content(JSON.parse(result));
});
ko.applyBindings(contentModel);
});
UI
<div class="ContentContainer">
<div data-bind='foreach: content'>
<div class="ContentElement" data-bind='css: { NotApproved: !Approved} '>
<div class="ContentValue" data-bind='html: Value'></div>
<div class="Approval">
<input type="checkbox" data-bind='checked: Approved, click: $root.ElementApprovalChanged' />
</div>
</div>
</div>
</div>
What is happening is on checkbox click I send request to webservice and if this call returns false I want to reset element’s Approved flag. And even whithout that, selecting checkbox should change div class attribute to mark it as NotApproved when needed. But none of this happens.
An observableArray only tracks the array. So if something is added, removed or replaced in the array this will trigger an update to your view.
An observableArray does NOT track the state of individual properties on the items in the array. So if you have an
Approvedflag on your objects this needs to be an observable for the UI to reflect changes to that property.So you would have something like:
(or if you want to be more consise:
)