knockout.js - 在组件绑定后应用自定义绑定

knockout.js - Apply custom binding after components are bound

我正在为 jquery ui 菜单小部件使用自定义 menu 绑定。在我的菜单的 HTML 中,我使用了一个组件。它看起来像这样:

<ul data-bind="menu: {...}">
    <!-- ko foreach: menuComponents -->
    <li>
        <div data-bind="component: $data"></div>
    </li>
    <!-- /ko -->
</ul>

我的自定义绑定在初始化菜单之前使用 applyBindingsToDescendents() 解析 ul 中的绑定。这是我绑定的简化版本。

ko.bindingHandlers.menu = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        ko.applyBindingsToDescendants(bindingContext, element);

        $(element).menu();

        return {controlsDescendantBindings: true};
    }
};

问题是组件是异步加载的。我正在使用自定义组件加载器,但我不确定这是否重要。副作用是 component 绑定在加载组件之前不会解析。所以加载顺序如下所示:

  1. 菜单绑定初始化开始
  2. 后代绑定由 applyBindingsToDescendents
  3. 应用
  4. jQuery 菜单小部件已初始化
  5. 组件被异步初始化和绑定

由于在应用绑定后才初始化组件,因此我的菜单无法正确呈现。

有什么方法可以强制同步应用组件后代绑定?或者有什么方法可以检测它们何时应用并刷新菜单小部件?

我目前的工作解决方案是完全避免使用组件。我只是使用模板绑定并手动应用视图模型。

<ul data-bind="menu: {...}">
    <!-- ko foreach: menuItems -->
    <li>
        <div data-bind="template: {name: $data.template, data: $data.data}"></div>
    </li>
    <!-- /ko -->
</ul>

我尝试对我的组件使用同步选项,但问题是它不保证同步操作。另一个解决方案是在 setTimeout 调用中绑定我的菜单,但我避免了此解决方案,因为它可能会导致其他问题。但这看起来像这样:

ko.bindingHandlers.menu = {
    init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        ko.applyBindingsToDescendants(bindingContext, element);

        setTimeout(function() {
            $(element).menu();
        });

        return {controlsDescendantBindings: true};
    }
};