I have a table like so:
<table>
<thead>
<tr>
<td>Column 1</td><td>Column 2</td>
</tr>
</thead>
<tr>
<td>static 1a</td><td>static 2a</td>
</tr>
<tr>
<td>dynamic 1b</td><td>dynamic 2b</td>
</tr>
<tr>
<td>dynamic 1c</td><td>dynamic 2c</td>
</tr>
</table>
The dynamic fields need to be a knockout foreach to iterate all the properties of the object. The only thing I can think to do is something like:
<tbody data-bind="foreachprop: properties">
<tr><td><span data-bind="text: propertyName"></span></td><td><span data-bind="text: value"></span></td></tr>
</tbody>
Which technically works, but it screws with my styling because the static row should be part of the tbody. What else can I bind to the for each? I must be missing a simple solution.
update: I'm actually not using "foreach", I'm using a custom function that iterates through the properties. When I try to use <!-- ko foreachprop:> properties -- I get the following console error:
Uncaught Error: The binding 'foreachprop' cannot be used with virtual elements
Here is the foreachprop function
ko.bindingHandlers.foreachprop = {
transformObject: function (obj) {
var properties = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var newObj = obj[key];
newObj.propertyName = key;
properties.push(newObj);
}
}
return properties;
},
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var value = ko.utils.unwrapObservable(valueAccessor()),
properties = ko.bindingHandlers.foreachprop.transformObject(value);
ko.applyBindingsToNode(element, { foreach: properties });
return { controlsDescendantBindings: true };
}
};
You can use foreach
without a container element (documentation: note 4) To handle this, you can use the containerless control flow syntax. You just need a specfial comment line where you can put your foreach
:
<tbody data-bind="">
<tr>
<td>static 1a</td><td>static 2a</td>
</tr>
<!-- ko foreach: properties -->
<tr>
<td>
<span data-bind="text: propertyName"></span>
</td>
<td>
<span data-bind="text: value"></span>
</td>
</tr>
<!-- /ko -->
</tbody>
If you are using a custom binding foreachprop
then you need to configure it work with virtual elements. You can do with after the bindingHandlers declaration with:
ko.virtualElements.allowedBindings.foreachprop = true;
You should note that you may need to rewrite your DOM manipulation logic inside your custom binding to support the virtual elements. You can find an extensive documentation on the virtualElements
helpers in the documentation: Creating custom bindings that support virtual elements
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With