Reputation: 2364
I have the following knockout and HTML:
<table>
<tbody data-bind="foreach: $root.selectedGroup().services">
<!-- ko if: ($index() % 2 === 0) -->
<tr>
<td data-bind="text:1">
</td>
<!-- /ko -->
<!-- ko ifnot: ($index() % 2 === 0) -->
<td data-bind="text: 0"></td>
</tr>
<!-- /ko -->
</tbody>
</table>
I only get the 1s, but no 0s. I have 5 items in my array
I should be displaying
1 0
1 0
1
but I only have
1
1
1
any ideas?
Upvotes: 1
Views: 342
Reputation: 9306
Here is one approach
<table>
<tbody data-bind="foreach: $root.services">
<!-- ko if: ($index() % 2 === 0) -->
<tr>
<!-- ko with: $root.services[$index()] -->
<td data-bind="text:$data"></td>
<!-- /ko -->
<!-- ko with: $root.services[$index()+1] -->
<td data-bind="text:$data"></td>
<!-- /ko -->
</tr>
<!-- /ko -->
</tbody>
It works by looking ahead in your array for the next item and then rendering the row on each second item.
I think it would be better to model this in your viewmodel though, this is a tortured solution.
Upvotes: 1
Reputation: 136074
Knockout does appear to be doing something weird here, but to be honest this way of fudging a 2 column layout using if/ifnot bindings to conditionally render the opening and closing <tr>
nodes seems a bit over-complicated.
What you could do is to rework your flat list into the appropriate rows/columns using a computed observable:
this.services = ["bar","foo","bar","foo","bar","foo","bar","foo","bar","foo","bar","foo","bar","foo"];
this.serviceRows = ko.computed(function(){
var result = [],
row,
colLength = 2;
//loop through items and push each item to a row array that gets pushed to the final result
for (var i = 0, j = this.services.length; i < j; i++) {
if (i % colLength === 0) {
if (row) {
result.push(row);
}
row = [];
}
row.push(this.services[i]);
}
//push the final row
if (row) {
result.push(row);
}
return result;
}, this);
And then render the template in a much more straight forward manner:
<table>
<tbody data-bind="foreach: serviceRows">
<tr data-bind="foreach: $data">
<td data-bind="text: ($index() % 2)"></td>
</tr>
</tbody>
</table>
Live example: http://jsfiddle.net/k773qf9o/
Upvotes: 0
Reputation: 6045
There is a slight issue with placement of container less if conditions
You written if/ifnot condition its like if/else so you get output either 0 or 1 for each row not both
<table>
<tbody data-bind="foreach: $root.selectedGroup().services">
<tr>
<!-- ko if: ($index() % 2 === 0) -->
<td data-bind="text:1">
</td>
<!-- /ko -->
<!-- ko ifnot: ($index() % 2 === 0) -->
<td data-bind="text: 0"></td>
<!-- /ko -->
</tr>
</tbody>
</table>
Working fiddle here
Upvotes: 0