0
votes

I am trying to update a javascript view model whenever a button is clicked by making an ajax call to the server and page doesn't seem to pick the newly assigned viewmodel after the first click.

I have a sample jsfiddle here

The below is my simple viewModel

var viewModel = {
model: null
};

Button click event handler and I am ensuring apply binding is called only once

$('#btnSearch').click(function () {
    // In actual scenario this data is returned from server side code
    var playerData = searchPlayers($('#drpCountry').val());
    // Data returned from server is then assigned to viewModel
    viewModel.model = playerData;
    if ($('#hdnKOHasBinded').val() === '0') {
        ko.applyBindings(viewModel);
        $('#hdnKOHasBinded').val('1');
    }
});

Please help

1

1 Answers

0
votes

I have updated your fiddle with a number of changes and comments to fix both issues with how to follow knockout convention, as well as javascript convention: http://jsfiddle.net/azurelogic/NsKPQ/2/

JS:

//Capitalize your object constructors if they are supposed to be created with 'new'
function Player(name, age) {
    //these would still work if they were like this: this.name = name;
    //they only need to be observable if you plan to change
    //one of the properties without swapping out the whole object
    this.name = ko.observable(name);
    this.age = ko.observable(age); 
}

function searchPlayers(country) {
    var players = null;
    if (country === 'spain') {
        players = [
        new Player('Nadal', 28),
        new Player('Ferrer', 32),
        new Player('Lopez', 29)];
    } else if (country === 'swiss') {
        players = [
        new Player('Federer', 32),
        new Player('Wawiranka', 28)];
    }
    return players;
}

var viewModel = {
    //changed the name from model to players and made the array observable. This is what drives your ability to update the DOM
    players: ko.observableArray()
};

$(function () {
    $('#btnSearch').click(function () {
        // In actual scenario this data is returned from server side code
        var playerData = searchPlayers($('#drpCountry').val());
        // Data returned from server is then assigned to viewModel
        viewModel.players(playerData);
    });

});

//Just go ahead and apply bindings immediately
ko.applyBindings(viewModel);

HTML:

<div>
    <select id="drpCountry">
        <option value="spain">spain</option>
        <option value="swiss">swiss</option>
    </select>
</div>
<input type="button" id="btnSearch" value="Search" />
<table>
    <thead>
        <tr>
            <th>Name</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: players">
        <tr>
            <td data-bind="text: name"></td>
            <td data-bind="text: age"></td>
        </tr>
    </tbody>
</table>