I am trying to bind a computed observable which internally uses a observable array. The "read" method does get called while loading. But the "write" method does not get called when the values in the table are changed and the focus is moved. Note that for simple computed observables , which do not wrap a array but a simple string, the "write" method works. However for this scenario it does not work. I looked on the Knockout api documentation and in online forums but could not find anything about this. Can someone please advice? Following is the HTML code
<thead>
<tr><th>People Upper Case Name</th></tr>
</thead>
<tbody data-bind="foreach: uppercasepeople">
<tr>
<td ><input type="text" data-bind="value: name"/></td>
</tr>
</tbody>
</table>
Following is the Java Script code
<script type="text/javascript">
var MyViewModel = function () {
var self = this;
var self = this;
//Original observable array is in lower case
self.lowercasepeople = ko.observableArray([
{ name: "bert" },
{ name: "charles" },
{ name: "denise" }
]);
//coputed array is upper case which is data-bound to the ui
this.uppercasepeople = ko.computed({
read: function () {
alert('read does get called :)...yaaaa!!!');
return self.lowercasepeople().map(function (element) {
var o = { name: element.name.toUpperCase() };
return o;
});
},
write: function (value) {
alert('Write does not get called :(... why?????');
//do something with the value
self.lowercasepeople(value.map(function (element) { return element.toLowerCase(); }));
},
owner: self
});
}
ko.applyBindings(new MyViewModel());
I have put the code similar to an example shown on the Knockout API documentation so people easily relate.
The computed observable that you have only deals with the array itself. The write
function would only get called if you tried to set the value of uppercasepeople
directly.
In this case, you would likely want to use a writeable computed on the person object itself and make the name observable. The writeable computed would then convert the name to upper-case and when written would populate the name observable with the lower-case value.