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

时间:2015-03-12 22:31:05

标签: javascript jquery-ui knockout.js

我正在为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. 组件初始化并异步绑定
  6. 由于在应用绑定之前组件尚未初始化,因此我的菜单无法正确呈现。

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

1 个答案:

答案 0 :(得分:0)

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

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