plamtod
plamtod

Reputation: 79

refresh UI after change observable array in Knockout

I heave this in html tbody data-bind="foreach: contacts"
and Knockout view model

var viewModel = function () {
    $this = this;
    $this.contacts = ko.observableArray();

$this.nextPage = function () {

        $.ajax({
            url: "/api/AddressBook",
            data: { pagesize: pageSize, currentpage: CPage },
            type: "GET"
        }).done(function (data) {

            var myKoObservableArray = $this.contacts; 

            myKoObservableArray.push(null);
            myKoObservableArray.push(data);

           alert(data[0].Name);

        });
}

$(document).ready(function () {
    $.ajax({
        url: "/api/AddressBook",
        data: { pagesize: 10,currentpage: 0 },
        type: "GET"
    }).done(function (data) {

        var vm = new viewModel();
        vm.contacts(data);
        ko.applyBindings(vm);
    });
});

First time page is loaded, table is filled from ajax call from $(document).ready. When I call nextPage from UI I make ajax call and alert(data[0].Name) show first element from returned data array. Is is different collection returned from server each time. The problem is that my table in UI not changed after change "contacts" observable array from second(and next) ajax call.

Upvotes: 1

Views: 5643

Answers (3)

Yes, you can call valueHasMutated function for your array:

yourArray.valueHasMutated();

If first didn't help you can do 'dirty' refresh:

self.refresh = function(){
    var data = self.array().slice(0);
        self.array([]);
        self.array(data);
    };

Here is working fiddle: http://jsfiddle.net/vyshniakov/FuEy6/2/

Upvotes: 5

plamtod
plamtod

Reputation: 79

Problem was that script file was included twice - at header and at bottom of the page. This probably broke binding.

Upvotes: 0

ebohlman
ebohlman

Reputation: 15003

myKoObservableArray.push(null);

Why are you doing this?

myKoObservableArray.push(data);

This adds a single element to the end contacts, namely a single reference to the entire array you received.

It sounds like you want to replace the contents of contacts with the array you got from your ajax call. If that's so, just replace those two statements with

$this.contacts(data);

If instead you want to append the new items to the existing ones, than use

ko.utils.arrayForEach(data, function(v) {$this.contacts.push(v)});

Upvotes: 2

Related Questions