Alex Dresko
Alex Dresko

Reputation: 5213

Binding to the same data twice doesn't work the second time in knockout

I submit for your consideration, this fiddle: http://jsfiddle.net/alexdresko/HFFUL/5/

There are two identical grids in the HTML, but only one of them populates when you click the "Load" button.

Is this due to my own fundamental misunderstanding of knockout, or is it a jqxgrid problem?

Here's the code:

<a href="#" data-bind="click: load">Load</a>

<div class="aGrid" data-bind="jqxGrid: { source: Stuff().People, columns: [ {text: 'Name', datafield: 'Name'} ], autoheight: true, sortable: true, altrows: true, enabletooltips:true }"></div>
<div class="aGrid" data-bind="jqxGrid: { source: Stuff().People, columns: [ {text: 'Name', datafield: 'Name'} ], autoheight: true, sortable: true, altrows: true, enabletooltips:true }"></div>

var dataFromServer = {
    People: ko.observableArray([{
        Name: "George"
    }, {
        Name: "Scot"
    }])
};

var viewModel = function () {

    this.Stuff = ko.observable({});
    this.load = function () {
        this.Stuff(dataFromServer);

    };
};

$(function () {
    var vm = new viewModel();
    ko.applyBindings(vm);
});

Upvotes: 2

Views: 1963

Answers (2)

Fabian Schmengler
Fabian Schmengler

Reputation: 24576

The problem is somewhere in source : Stuff().People because you explicitly get the value of the Stuff observable here and access the People property of that. Changing Stuff itself does not change this bound observable array.

However, there is a overall more elagant solution, where you also don't have to make the dataFromServer an observable itself:

HTML:

<a href="#" data-bind="click: load">Load</a>

<div class="aGrid" data-bind="jqxGrid: { source: Stuff.People, columns: [ {text: 'Name', datafield: 'Name'} ], autoheight: true, sortable: true, altrows: true, enabletooltips:true }"></div>
<div class="aGrid" data-bind="jqxGrid: { source: Stuff.People, columns: [ {text: 'Name', datafield: 'Name'} ], autoheight: true, sortable: true, altrows: true, enabletooltips:true }"></div>

JavaScript:

var dataFromServer = [{
        Name: "George"
    }, {
        Name: "Scot"
    }];

var viewModel = function () {

    this.Stuff = { People: ko.observableArray([]) }
    this.load = function () {
        for (i=0; i < dataFromServer.length; ++i) {
            this.Stuff.People.push(dataFromServer[i]);
        }

    };
};


$(function () {

    var vm = new viewModel();
    ko.applyBindings(vm);

});

Forked JSFiddle

Upvotes: 2

Matt Burland
Matt Burland

Reputation: 45155

Not sure about the cause, but when I wrapped your two grids in a div like this:

<div data-bind="if: Stuff().People">

It worked fine. Of course, this hides your grids altogether until you click load.

Fiddle

Upvotes: 0

Related Questions