0

My problem scenario is almost identical to this one but the table I'm drawing has TD cells with more complex bindings, each binding unique to the column being bound. Sometimes it's just the HTML that's unique.

In other words, it isn't good enough to loop the columns using a databind=foreach and simply nest a <TD> that does a text binding.

I can get my table to render on initial page draw, using a template{nodes:xxx} binding, where I pass in an array of DOM nodes.. like this:

    <table>
        <thead>
            <tr>
              <!-- ko foreach: ColumnModel.VisibleColumns -->
                <th data-bind="click:$root.ColumnModel.ColumnSortClick,text:ColName"></th>
              <!-- /ko -->
            </tr>
        </thead>
        <tbody>
            <!-- ko template: { nodes: ColumnModel.getRowTmplNodes(), foreach: DataItems} -->
            <!-- /ko -->
        </tbody>
    </table>

The documentation states that the DOM nodes you pass to this variable are not allowed to be an observableArray. So, as you can imagine, when I allow the users to update the column model, only my header labels change in the <THEAD>, but the data columns do not update.

What do I do?

bkwdesign
  • 1,953
  • 2
  • 28
  • 50
  • Ok, I found a way to make this work, and switched from using the `template` binding to a custom binding handler [thanks to Michael Best](https://groups.google.com/forum/#!searchin/knockoutjs/template$20nodes%7Csort:relevance/knockoutjs/dsikE_EAzjo/zGKuaB3thvYJ) – bkwdesign Sep 18 '17 at 16:17
  • You can post that as an answer and accept it. – Nisarg Shah Sep 19 '17 at 07:12

1 Answers1

1

Solved by using a custom knockout binding described originally here by Michael Best

HTML:

<table>
    <thead>
       <tr>
        <!-- ko foreach: ColumnModel.VisibleColumns -->
          <th data-bind="click:$root.ColumnModel.Column_Click" style="cursor:pointer;"><span data-bind="visible:SortDirection,css:IconClass" style="font-size:small"></span><span data-bind="text:ColName"></span></th>
        <!-- /ko -->
       </tr>
    </thead>
    <tbody data-bind="foreach:{data:DataItems,as:'thg'}">
       <tr data-bind="nodes: $root.ColumnModel.getRowTemplate()"></tr>                
    </tbody>
</table>

KO BINDING:

//THANK YOU, MICHAEL BEST:
ko.bindingHandlers.nodes = {
    init: function () {
    return {controlsDescendantBindings: true};
    },
    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
    var nodes = ko.unwrap(valueAccessor());
    ko.virtualElements.setDomNodeChildren(element, nodes);
    ko.applyBindingsToDescendants(bindingContext, element);
    }
};
ko.virtualElements.allowedBindings.nodes = true;
bkwdesign
  • 1,953
  • 2
  • 28
  • 50