James Radford James Radford - 4 months ago 13
Javascript Question

i'm not seeing knockout value coming through onto my bound textfield

I have the following code although I'm not seeing the value of the firstname coming through onto the form textbox? I can see in firebug that the value is correct?
Any help much appreciated!

Firebug - console window

pageModel.firstname() // shows value: 'Jane'


HTML

<input id="Firstname" name="Firstname" data-bind="value: pageModel.firstname'" />


JS

$(function() {

pageModel = (function() {
var init = function(data) {
this.firstname = ko.observable(data.Member.FirstName);
...
...
};
return { init: init }; // Revealing module pattern
})();

ko.applyBindings(pageModel);

var serverModel = <%=ViewData.Model.ToJson() %>;

pageModel.init(serverModel);
});


JSON object

{"Member":{FirstName: 'Jane'}}

Answer

There are a couple of problems there:

  1. You're applying bindings before you initialize the view model. If you open your web console, you'll see an error from KO saying it has no idea what pageModel is.

  2. Even once you initialize the model, it still doesn't have a pageModel property. Just a firstname property.

  3. You have an extra ' at the end of the binding.

Separately, your code is falling prey to The Horror of Implicit Globals because you're not declaring pageModel anywhere.

Some fixes:

$(function() {

    // Added `var` here
    var pageModel = (function() {          
        var init = function(data) {
            this.firstname = ko.observable(data.Member.FirstName);
            ...
            ...
        };
        return { init: init };  // Revealing module pattern
    })();


    var serverModel = <%=ViewData.Model.ToJson() %>;

    pageModel.init(serverModel);

    // Moved this to end
    ko.applyBindings(pageModel);
});

and in the HTML:

<input id="Firstname" name="Firstname" data-bind="value: firstname" />
<!-- No `pageModel.` here -------------------------------^        ^
     No single quote here ---------------------------------------/
-->

Live Example (source)

If you really want to apply the bindings before calling pageModel.init, you'll need to do something to create the firstname observable, and then later in init update that observable using the data argument (rather than creating a new one).

Comments