0
votes

I am using knockout mapping library to bind JSON data from .NET service to a property in KO view model, in which the property has an array of objects that I need to loop through and render on the screen.

The .NET model:

new{
    count = count,
    total = total,
    rows = items,
}

the rows property holds list of objects, which needs to be rendered into a table using KO.

I tired using

<!-- ko foreach: masterData().rows-->
<tr>
    <td><span data-bind='text:  Id' /></td>
    <td><span data-bind='text:  Name' /></td>
    <td><span data-bind='text:  Description' /></td>
    <td><span data-bind='text:  Status' /></td>
</tr>
<!-- /ko -->

where the masterData is an observable. After data load, it renders nothing inside the table. As a workaround, I have changed the model the observable to observableArray([])

new List<dynamic> { 
    new
    {
        count = recCount,
        total = total,
        rows = items,
    }};

and changed the rendering logic to

<!-- ko foreach: masterData -->
<!-- ko foreach: rows-->
<tr>
    <td><span data-bind='text:  Id' /></td>
    <td><span data-bind='text:  Name' /></td>
    <td><span data-bind='text:  Description' /></td>
    <td><span data-bind='text:  Status' /></td>
</tr>
<!-- /ko -->
<!-- /ko -->

Now it works as expected. There should be a better way of dealing with this or I am missing something I suppose. Also, I needed to loop through this list in order to access other properties.

EDIT 1:

http://jsfiddle.net/krishnasarma/hdt9ehth/

1
I think you just need to make your first one foreach: masterData().rows(). - Roy J
That is strange... if think it should work fine. Provide a JSFiddle with your code and an example data - Fabio Luz

1 Answers

2
votes

well i tweaked your code little bit to make it ideal . I see not point looping masterData for getting rows data .

we can now use with binding which is perfect for such scenario stated above.

view:

<table>
    <thead>
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Description</th>
            <th>Status</th>
        </tr>
    </thead>
    <tbody data-bind="with:masterData2">
        <!-- ko foreach:rows -->
        <tr>
            <td><span data-bind='text:  Id' /></td>
            <td><span data-bind='text:  Name' /></td>
            <td><span data-bind='text:  Description' /></td>
            <td><span data-bind='text:  Status' /></td>
        </tr>
        <!-- /ko -->
    </tbody>
</table>

viewModel:

var VM = {
    masterData: ko.observable([]), //initializing 
    masterData2: ko.observable([])
}

sample working fiddle here

If you want to in a Lazy Loading way check here