在嵌套的 dom 元素上敲除多个绑定

Tom*_*Tom 5 javascript dom knockout.js

我已经设法让自己在我正在进行的项目中遇到了一些麻烦。

最初,该站点有一个使用 Knockout 的页面,其他页面使用 jQuery。由于 Foundation 模态将自身置于 body 元素的根中的一些问题,我最终将此页面的 viewmodel 绑定应用到 body 元素。

快进 4 个月,在没有预见到我现在遇到的麻烦的情况下,我在 Knockout 中重建了我们的购物篮。购物篮在每个页面上都可见,并使用 ZF2 部分包含在内。

回到我 4 个月前工作的页面,它完全被控制台中的错误消息破坏了:

Uncaught Error: You cannot apply bindings multiple times to the same element.
Run Code Online (Sandbox Code Playgroud)

下面是一些代码来显示我的布局:

<html>
    <head>
        <title>My Website</title>
    </head>
    <body> // 4 month old SPA bound here
        <nav>
            <div id='shopping-basket'> // Shopping basket bound here
                ...
            </div>
        </nav>
        <div id='my-app'>
           ...
        </div>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

JavaScript:

var MyAppViewModel = function() {
   // logic
};

var ShoppingBasketViewModel = function() {
    //logic
};

ko.applyBindings(new MyAppViewModel(), document.body);
ko.applyBindings(new ShoppingBasketViewModel(), document.getElementById('shopping-basket');
Run Code Online (Sandbox Code Playgroud)

如果我有时间,我可以返回并重新设计原始应用程序,使其位于它自己的 div 容器中,该容器将与篮子并排放置,但不幸的是,这不是一个选项。

另一种选择是放弃我在购物篮上所做的最后一点工作,并用 jQuery 替换它,但这将意味着失去一周的工作量。

无论如何,当我应用绑定时,我可以让两个视图模型并排工作,同时嵌套在 Dom 中,并保持彼此独立?

小智 6

我有一些类似的问题。我需要将绑定应用于特定的嵌套元素,并首先从文档上的绑定开始。同样的问题。我的解决方案是添加一些忽略元素部分,而不是手动绑定特定元素。

1) 添加自定义绑定,以便您可以跳过特定购物篮上的绑定:

ko.bindingHandlers.stopBinding = {
    init: function() {
         return { controlsDescendantBindings: true };
    }
};
ko.virtualElements.allowedBindings.stopBinding = true;
Run Code Online (Sandbox Code Playgroud)

2) 在您的 html 中添加自定义绑定(围绕您的购物篮):

<html>
<head>
    <title>My Website</title>
</head>
<body> // 4 month old SPA bound here
    <nav>
        <!--  ko stopBinding: true -->
        <div id='shopping-basket'> // Shopping basket bound here
            ...
        </div>
        <!--  /ko -->
    </nav>
    <div id='my-app'>
       ...
    </div>
</body>
Run Code Online (Sandbox Code Playgroud)

3)像你已经做的那样应用你的绑定:

ko.applyBindings(new MyAppViewModel(), document.body);
ko.applyBindings(new ShoppingBasketViewModel(), document.getElementById('shopping-basket');
Run Code Online (Sandbox Code Playgroud)

4) 由于您的自定义绑定处理程序,第一个绑定将跳过购物篮,而您的第二个绑定将显式绑定购物篮。

我没有在你的具体例子中测试过上面的代码,但它应该为你指明正确的方向。