Frage

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.

War es hilfreich?

Lösung

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.

Andere Tipps

var MyViewModel = function () {

var self = this;

//Original observable array is in lower case
self.lowercasepeople = ko.observableArray([
{ name: "bert" },
{ name: "charles" },
{ name: "denise" }
]);

self.recententlyChangedValue = ko.observable();

//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('It will be called only when you change the value of uppercasepeople field');
        //do something with the value 

         self.recententlyChangedValue(value);             
    },
    owner: self
});
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top