1

I'm trying to load up a simple view model that has two models, Profile which is a ko.observable() and requests, which is a ko.observableArray().

When I apply the bindings and then try to bind to ether profile.field or foreach: requests, I get no output, no javascript or binding errors. But when I dump out ko.toJSON(self.profile) or ko.toJSON(self.requests), I get in fact have the data, it's just not binding and I'm not sure why, any ideas what I'm doing wrong.

Here are my models

var Profile = function(profile) {   
    var self = this;

    self.id                  = ko.observable(profile.id);
    self.user_id             = ko.observable(profile.user_id);
    self.first_name          = ko.observable(profile.first_name);
    self.last_name           = ko.observable(profile.last_name);
    self.age                 = ko.observable(profile.age);
    self.email               = ko.observable(profile.email);
    self.area                = ko.observable(profile.area);
    self.favorite_restaurant = ko.observable(profile.favorite_restaurant);
    self.avatar              = ko.observable(profile.avatar);
    self.on_mailing_list     = ko.observable(profile.on_mailing_list);
}
var Request = function(request) {
    var self = this;

    self.id           = ko.observable(request.id);
    self.user_id      = ko.observable(request.user_id);
    self.title        = ko.observable(request.title);
    self.participants = ko.observable(request.participants);
    self.food_type    = ko.observable(request.food_type);
    self.event_date   = ko.observable(request.event_date);
    self.time_of_day  = ko.observable(request.time_of_day);
    self.area         = ko.observable(request.area);
    self.description  = ko.observable(request.description);
    self.status       = ko.observable(request.status);
}

Here is my ViewModel

var MasterViewModel = function() {
    var self = this;

    self.profile       = ko.observable();
    self.requests      = ko.observableArray();
    self.notifications = ko.observableArray();

    // load the users profile 
    $.getJSON('/profiles/load', {}, function(profile) {     
        self.profile = new Profile(ko.toJS(profile));
        console.log(ko.toJSON(self.profile));

        // load the users requests
        $.getJSON('/request/load', {}, function(requests){
            var mappedRequests = $.map(requests, function(request) {
                return new Request(request);
            });
            self.requests = mappedRequests;
            console.log(ko.toJSON(self.requests));
        });         
    });
}

Here are the simple bindings I'm trying to apply

<h2 data-bind="text: profile.first_name"></h2>

<ul data-bind="foreach: requests">
    <li data-bind="text: title"></li>
</ul>

And of course I'm applying the knockout bindings in document ready

  <script>
    $(document).ready(function() {
      // bind the ViewModel
      ko.applyBindings(new MasterViewModel());
    });
 </script>

2 Answers 2

1

You should set the observables not override them with a new value.

You wrote :

self.profile = new Profile(ko.toJS(profile));

You should write this :

self.profile(new Profile(ko.toJS(profile)));

Why? Because this way, ko knows that the profile changed and it has to refresh the view.

Same problem with :

self.requests = mappedRequests;

which should be :

self.requests(mappedRequests);
Sign up to request clarification or add additional context in comments.

1 Comment

oh man...I can't believe I missed that...time to sleep. Thank you very much!
0

you need to update the value of the observables and not it's references. Also you will need to access the profile value as a function

<h2 data-bind="text: profile().first_name">

check this fiddle http://jsfiddle.net/victorrseloy/qFnUC/1/

    var i = 0;

function Profile(){
    var self = this;
    this.first_name = ko.observable("profile"+(i++));
}

function ViewModel(){
    this.profile= ko.observable(new Profile());
    this.requests= ko.observableArray([{title:"t1"},{title:"t2"}]);
}


var viewModel = new ViewModel()

function changeReference(){

    viewModel.profile = new Profile();
    viewModel.requests = [{title:"t1"+i},{title:"t2"+i}];

}

function changeValue(){
   viewModel.profile(new Profile());
   viewModel.requests([{title:"t1"+i},{title:"t2"+i}]);
}

ko.applyBindings(viewModel)

html:

<h2 data-bind="text: profile().first_name"></h2>

<ul data-bind="foreach: requests">
    <li data-bind="text: title"></li>
</ul>
<a href="#" onclick="changeReference()">change reference</a>
<a href="#" onclick="changeValue()">change value</a>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.