Reputation: 1625
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
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
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
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 ...> </span>
(the latter being a countermeasure to an IE6 bug).
Upvotes: 0
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