Custom binding(?) that adds some standard Knockout bindings to child nodes

半城伤御伤魂 提交于 2019-12-10 22:25:48

问题


I want to implement using Knockout something easily reusable (probably, custom binding) that could apply mix of standard bindings: the foreach binding to a tbody node and another standard bindings (visible and css) to its tr child nodes.

AFAIK, the best way it can be achieved is to write a custom binding.
I want to use it like that:

<table>
    <tbody data-bind="tableRows: { rows: unfilteredItems, filter: rowFilter }">
        <tr data-bind="possibly, some hard coded bindings including visible and css bindings">...</tr>
    </tbody>
</table>

, where unfilteredItems and rowFilter are some observables.

I want the custom binding to 'transform' this into the following and let KO process this as it was initially in the layout:

<table>
    <tbody data-bind="foreach: unfilteredItems">
        <tr data-bind="visible: rowFilter($data), css: rowClass($data), and now hard coded bindings, if any">...</tr>
    </tbody>
</table>

Here rowClass() is a function contained in the component and just returns a string that should be appended to the tr's class attribute based on the current $data.

I know how to apply the foreach binding to the node that my binding is applied to:

ko.bindingHandlers.tableRows = {
    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        var options = valueAccessor(),
            rows = options.rows;

        ko.applyBindingsToNode(element, { foreach: rows }, bindingContext);
    }
};

This part is working perfectly.

But I can't find anywhere how to add bindings to the child tr nodes, so that when the foreach binding would process child nodes, that bindings (and all bindings that already contained in the child layout) were applied to and processed in the same manner as they were initially in the layout.

I could try to manually add the required bindings to the child tr nodes as a string in the init function using JS DOM API, but I have feeling that it should be cleaner solution using some KO API.

Also, I need the custom binding to properly handle cases when there initially are another bindings on the tr nodes including both visible and css bindings.

My project uses Knockout 2.2.1 and it would be nice if the solution doesn't rely on the Knockout 3 features, if possible.

Could someone suggest how to achieve this?


回答1:


I think you should be able to modify the data-bind attributes of the inner elements of the foreach using jQuery's data or similar. The outer would be processed by Knockout before its inner parts would. I haven't tried such things myself.

In fact, since you're just doing boilerplate-rewrite, you could use jQuery to find and rewrite the tags before you apply Knockout bindings at all. That would save you the custom binding handler.




回答2:


You can create your own tr template for foreach binding like

<script type="text/html" id="rowTemplate">

    <tr data-bind="css:{'success': $root.rowClass($data)}, visible: $root.rowFilter($data)">
        <td data-bind="text: name"></td>
    </tr>

</script>

and render it inside your custom binding as

ko.applyBindingsToNode(element, {template:{foreach: data, name: "rowTemplate"}}, bindingContext);
return { controlsDescendantBindings: true };


来源:https://stackoverflow.com/questions/32811802/custom-binding-that-adds-some-standard-knockout-bindings-to-child-nodes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!