CyclingFreak
CyclingFreak

Reputation: 1625

Knockoutjs mapping is not binding

I wanted to use the KnockoutJS mapping plugin for the first time because it can save me a lot of code. But altough the opject is mapped, it is not binding to the view. My code is as follow:

JavaScript

...
//global variables
var mv;
...
function viewmodel() {
    var self = this;

    self.searchViewModel = ko.mapping.fromJS({});
}
...
//load function
$().ready(function () {
    mv = new viewmodel();
    doSearch();
    ko.applyBindings(mv);
...
}
function doSearch() {
    var params = "{'_search':'" + JSON.stringify(searchObject) + "'}";
    $("#_pnlMachineList").mask("Loading...");

    $.ajax({
        type: "POST",
        url: "machinepark2.aspx/doSearch",
        data: params,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        dataFilter: function(data) {
            // This boils the response string down 
            //  into a proper JavaScript Object().
            var msg = eval('(' + data + ')');

            // If the response has a ".d" top-level property,
            //  return what's below that instead.
            if (msg.hasOwnProperty('d'))
                return msg.d;
            else
                return msg;
        },
        success: function (msg) {
            ko.mapping.fromJS(msg, {}, mv.searchViewModel);
        },
        error: function (msg) {
            //document.location = "/errorPage.aspx";
        }
    });
}

HTML

Count: <span data-bind="text: searchViewModel.searchCount"></span>
<br />
<table class="table">
    <thead>
        <tr class="text_bold">
            <th>Name</th>
            <th>Type</th>
            <th>Model</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: searchViewModel.machines">
        <tr style="cursor:pointer;" data-bind="attr: { 'data-guid': GUID }, click: loadmachine">
            <td data-bind="text: EndUserMachineName"></td>
            <td><img alt="" style="position: relative;" data-bind="attr: { src: TypeImage }"></td>
            <td data-bind="html: ManufacturerModel"></td>
        </tr>
    </tbody>
</table>

When the doSearch function has been executed, I can view the mv.searchViewModel in the firebug console. All properties are nicely put in observables: enter image description here

And mv.searchViewModel.searchCount() gives me an integer: 2.

But the count label and the table are not filled. What am I doing wrong?

Edit: Firebug doesn't give any bug.

Upvotes: 0

Views: 816

Answers (1)

pax162
pax162

Reputation: 4735

You mostly forgot some () after searchViewModel. Here is the corrected code (fiddle:http://jsfiddle.net/hv9Dx/7/) :

html:

Count: <span data-bind="text: searchViewModel().searchCount"></span>
<br />
<table class="table">
    <thead>
        <tr class="text_bold">
            <th>Name</th>
            <th>Type</th>
            <th>Model</th>
        </tr>
    </thead>    
    <tbody data-bind="foreach: searchViewModel().machines">
        <tr style="cursor:pointer;" data-bind="attr: { 'data-guid': GUID }">
            <td data-bind="text: EndUserMachineName"></td>
            <td><img alt="" data-bind="attr: { src: TypeImage }" /></td>
            <td data-bind="text: ManufacturerModel"></td>
        </tr>
    </tbody>
</table>

js:

var dataFromServer = {
    searchCount:5,
    machines:[{
        GUID:"123",
        EndUserMachineName:"1",
        TypeImage:"https://i.chzbgr.com/maxW500/7879380224/hE2041EA3/",
        ManufacturerModel:"lorem lorem"
    }
        ]
}
var ajaxSim = function(callback){
    setTimeout(function(){
        callback(dataFromServer);
    },1000);
}

var mv;

function viewmodel() {
    var self = this;
    self.searchViewModel = ko.observable({searchCount:4, machines:[]});
}

mv = new viewmodel();
doSearch();
ko.applyBindings(mv);

function doSearch() {
    ajaxSim(
        function (msg) {
            console.log(msg)

            mv.searchViewModel(ko.mapping.fromJS(msg));

    });
}

Upvotes: 2

Related Questions