Yasir
Yasir

Reputation: 1625

Binding not working for collections in knockoutjs

I am trying to use knockout.js to show a specification object on the UI. The specification has a name and it has a few parameterInfo rows. Each ParameterInfo row has a ParameterPartNumber and a bunch of SignalInputs. Each SignalInput has just one property called Name. I am able to show the specification name, the parameterInfo rows and ParameterPartNumber but am not able to show the bunch of SignalInput Names that I have even though the SpecificationModel has the values. I am using the following code:

HTML code:

<div id="specificationHeader">

    Name : <input data-bind='value: Name' />
    <br />
    <br />

</div>

<table>
    <thead>
        <tr>
            <th>
                Parameter Part
            </th>

            <th>
                Signal Inputs
            </th>            
       </tr>
    </thead>
    <tbody data-bind="foreach: ParameterInfos">
        <tr>
            <td>
                <input data-bind='value: ParameterPartNumber' />
            </td>

            <td>
                <ul data-bind="foreach: SignalInputs">                    
                    <li><span data-bind='text: Name' /></li>
                </ul>
            </td>            
        </tr>
    </tbody>
</table>

Javascript/Knockout code:

<script type="text/javascript">

    var SpecificationModel = function (specification) {

        var self = this;

        self.Name = ko.observable(specification.Name);

        self.ParameterInfos =   ko.observableArray(ko.utils.arrayMap(specification.ParameterInfos, function (ParameterInfo) {
            return { ParameterPartNumber: ParameterInfo.ParameterPartNumber, SignalInputs: ko.observableArray(ParameterInfo.SignalInputs) };
        }));

    };

    var specificationData = '@Html.Raw(ViewBag.SpecificationData)';
    var viewModel = new SpecificationModel($.parseJSON(specificationData))
    ko.applyBindings(viewModel);

</script>

When I run the program in debug mode, I can see the following values:

var specificationData = '{"Name":"Specification One",
                          "ParameterInfos": [{"ParameterPartNumber":"26-20700-002", "SignalInputs":[{"Name":"Park Brake"},{"Name":"Neutral"}]} ]}';

It's strange because I was able to get an almost similar example working thanks to the answers for the following question:

Need to pass initial viewmodel data from ASP.NET MVC to knockout.js

Still, somehow the binding code is not working. What am I missing?

EDIT:

Ok, the following lines work:

<td data-bind="foreach: SignalInputs">
    <ul >                    
        <li><span data-bind='text: Name' /></li>
    </ul>
</td>

But, the following lines don't

<td>
    <ul data-bind="foreach: SignalInputs">                    
        <li><span data-bind='text: Name' /></li>
    </ul>
</td>  

Any idea why? The latter site of lines work in the other stackoverflow example question I cited.

Upvotes: 0

Views: 5502

Answers (4)

arb
arb

Reputation: 7863

In my experience when you run into weird binding errors, it often stems from the for-each binding. Because I've had so many issues with it, I pretty much just go the "containerless" route:

<!-- ko foreach: myItems -->
    <li>Item <span data-bind="text: $data"></span></li>
<!-- /ko -->

Upvotes: 4

MickJuice
MickJuice

Reputation: 539

Not sure this is relevant since this answer was posted so long ago but I was having an issue with foreach as well. I noticed that the error was coming from a jquery call in knockout (i was using knockout-2.0.0) and jquery-2.1.1. When I updated to knockout-3.1.0, this problem was solved.

2.0.0 was installed when I installed knockout.mapping via nuget and it probably depends on 2.0.0 at least. Hope this helps someone...

Upvotes: 0

Rae
Rae

Reputation: 76

I remember reading in the KnockoutJS documentation that the bindings run into issues with empty elements like <span .... /> and they suggest using <span ...></span> or even <span ...>&nbsp;</span> (the latter being a countermeasure to an IE6 bug).

Upvotes: 0

Shaun
Shaun

Reputation: 1341

I was having problems binding, but my issue turned out to be because I was using an early version of (knockout 1.2.1) that didn't support the foreach binding. It didn't throw an error for an unrecognised binding function though, just when I tried to reference an element within the collection I was supposedly binding to making it hard to debug.

In the end I used a template binding as per the answer here: Stackoverflow: knockout javascript foreach binding

Upvotes: 0

Related Questions