自定义绑定(?),将一些标准的 Knockout 绑定添加到子节点

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

我想使用 Knockout 实现一些易于重用的东西(可能是自定义绑定),可以应用标准绑定的混合:foreach 绑定到 tbody 节点和另一个对其 tr 子节点的标准绑定(visiblecss)。

据我所知,实现它的最佳方法是编写自定义绑定。
我想这样使用它:

<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>

,其中 unfilteredItemsrowFilter 是一些 observables.

我希望自定义绑定到 'transform' 到以下内容,让 KO 处理它,因为它最初在布局中:

<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>

这里 rowClass() 是一个包含在组件中的函数,只是 returns 一个字符串,应该根据当前的 trclass 属性附加$data.

我知道如何将 foreach 绑定应用到我的绑定应用到的节点:

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

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

这部分工作完美。

但是我在任何地方都找不到如何将绑定添加到子 tr 节点,以便当 foreach 绑定处理子节点时,绑定(和已经包含在子布局中的所有绑定)都以与它们最初在布局中相同的方式应用和处理。

我可以尝试使用 JS DOM API 在 init 函数中将所需的绑定作为字符串手动添加到子 tr 节点,但我有感觉使用一些 KO API.

应该是更清洁的解决方案

此外,我需要自定义绑定来正确处理 tr 节点上最初有另一个绑定的情况,包括 visiblecss 绑定。

我的项目使用 Knockout 2.2.1,如果可能的话,如果解决方案不依赖于 Knockout 3 功能就好了。

有人可以建议如何实现吗?

我认为您应该能够使用 jQuery's data 或类似方法修改 foreach 内部元素的 data-bind 属性。外部将在其内部部分之前由 Knockout 处理。我自己没试过这样的东西。

事实上,由于您只是在进行样板重写,因此您可以在应用 Knockout 绑定之前使用 jQuery 来查找和重写标签。这将为您节省自定义绑定处理程序。

您可以为 foreach 绑定创建自己的 tr 模板,例如

<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>

并将其在您的自定义绑定中呈现为

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