Reputation: 658
Essentially I have the following 2 dimensional array:
"items":
[
["",""],
["",""],
["",""]
]
I want to iterate over this collection using knockout and I got the following:
<!-- ko foreach: items -->
<tr>
<td>
<button type="button" class="btn btn-default btn-xs"><i class="fa fa-plus"></i> Column</button>
</td>
<!-- ko foreach: $data -->
<td>
<input type="text" class="form-control" data-bind="value: $data" />
</td>
<!-- /ko -->
</tr>
<!-- /ko -->
However, this does not appear to be working. Any ideas?
Thanks in advance
G
Upvotes: 2
Views: 1762
Reputation: 16688
Virtual bindings are just comments and sometimes can get moved around by the browser as it tries to correct the HTML markup. In this case, the browser surrounds your <tr>
tag with a <tbody>
tag as required by the HTML spec. The <tbody>
starts right before the <tr>
tag and ends right before the closing </table>
tag. Thus the virtual element closing comment is now in the wrong place:
<table>
<!-- ko foreach: items -->
<tbody>
<tr>
...
</tr>
<!-- /ko -->
</tbody>
</table>
The key to fixing this is to add the <tbody>
tag to your markup:
<table>
<tbody>
<!-- ko foreach: items -->
<tr>
...
</tr>
<!-- /ko -->
</tbody>
</table>
Upvotes: 4
Reputation: 37530
You've run into an edge case where Knockout isn't able to find the second <!-- /ko -->
tag when it's inside of a <table>
.
The following markup causes an error (in Chrome it's saying Uncaught Error: Cannot find closing comment tag to match: ko foreach: items
):
<table>
<!-- ko foreach: items -->
<tr>
<td>
<button type="button" class="btn btn-default btn-xs"><i class="fa fa-plus"></i> Column</button>
</td>
<!-- ko foreach: $data -->
<td>
<input type="text" class="form-control" data-bind="value: $data" />
</td>
<!-- /ko -->
</tr>
<!-- /ko -->
</table>
Fiddle: http://jsfiddle.net/63rkQ/
But if you change the outer foreach to be on the <table>
tag, it works:
<table data-bind="foreach: items">
<tr>
<td>
<button type="button" class="btn btn-default btn-xs"><i class="fa fa-plus"></i> Column</button>
</td>
<!-- ko foreach: $data -->
<td>
<input type="text" class="form-control" data-bind="value: $data" />
</td>
<!-- /ko -->
</tr>
</table>
Fiddle: http://jsfiddle.net/63rkQ/1/
Try not to use virtual elements for your bindings unless you absolutely have to. I've run into strange cases where they work on some browsers but not others. They're difficult to debug.
You can see that moving the virtual element outside of the <table>
also works (at least in Chrome) but I don't think that's what you wanted)...
Fiddle: http://jsfiddle.net/63rkQ/2/
Upvotes: 0