I'm working on some custom bindings, and in one I'd like to be able to show a table from some arrays of strings.
I simplified it down to this custom binding:
ko.bindingHandlers.table = {
init: function tableBinding(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
element.innerHTML = tableTemplate;
var innerBindingContext = bindingContext.createChildContext(valueAccessor());
ko.applyBindingsToDescendants(innerBindingContext, element);
return {
controlsDescendantBindings: true
};
}
};
This is the contents of template:
<!-- if: head && head.length -->
<thead>
<tr data-bind="foreach: head">
<th data-bind="text: $rawData">not working th</th>
</tr>
</thead>
<!-- /ko -->
<tbody data-bind="foreach: rows">
<tr data-bind="foreach: $data">
<td data-bind="text: $data">not working td</td>
</tr>
</tbody>
And some example data.
ko.applyBindings({
table: {
head: ["Name", "Position"],
rows: [
["John", "Janitor"],
["Mike", "IT"],
["Paul", "HR"],
["Rick", "Coffee Fetcher"]
]
}
});
I'm using Knockout 3.0, however anything that'd work on Knockout 2.x would also work here. If you look at the fiddle, the <thead>
part is displaying properly, but the bindings for the body aren't. It works fine if I inline the template, and use a with
binding, as in, with: table
.
I have to confess, at the moment I am not following all you are doing here, but I can tell enough that your example will work if your if
statement uses ko if:
instead of just if:
.
So instead of this:
<!-- if: head && head.length -->
go with this:
<!-- ko if: head && head.length -->
The containerless binding syntax requires <!-- ko ... --> ... <!-- /ko -->
as the virtual container. Thus if an html comment syntax just has <!-- if ... -->
, knockout does not do anything special.
From the knockout documentation for the "if" binding:
http://knockoutjs.com/documentation/if-binding.html
The
<!-- ko -->
and<!-- /ko -->
comments act as start/end markers, defining a “virtual element” that contains the markup inside. Knockout understands this virtual element syntax and binds as if you had a real container element.