James Radford
James Radford

Reputation: 1855

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'}}

Upvotes: 1

Views: 75

Answers (4)

Ankit Tanna
Ankit Tanna

Reputation: 1819

You can check the context of your data binding. It's already pageModel. You do not need to repeat the context to knockout. As good as data-bind="with: pageModel" and the bindings inside this element will not need pageModel to be repeated.

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1075219

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).

Upvotes: 1

Wayne Ellery
Wayne Ellery

Reputation: 7958

The main issue is that you should just be using data-bind="value: firstname" without the ' and the pageModel.

It's a lot easier to read if you create a ViewModel which you can create an object of.

html:

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

js:

$(function() {
    var serverModel = <%=ViewData.Model.ToJson() %>;
    var viewModel = new ViewModel(serverModel);
    ko.applyBindings(viewModel);
});

var ViewModel = function(serverModel) {
    var self = this;

    self.firstname = ko.observable(serverModel.Member.FirstName);
};

Upvotes: 0

PatrickSteele
PatrickSteele

Reputation: 14687

Your view model is pageModel so your bindings just reference objects on the view model. Change your binding to:

data-bind='value: firstName'

And you should be all set.

Upvotes: 1

Related Questions