两个单独的模型 - 您不能多次将绑定应用于同一个元素

时间:2016-11-21 09:17:51

标签: javascript jquery html knockout.js

我有一个MVC应用程序,它有一个链接到视图模型的内容页面。它运作良好。但是只要我将视图模型添加到我的内容页面(在我的布局中生成),我就会收到错误:

  

您不能多次将绑定应用于同一元素。

我创建了“Sections”并尝试绑定到该部分,如下所示。

//在我的布局页面中。

<div class='liveExample' id="sectionOne">   
    <p>First name: <input data-bind='value: firstName' /></p> 
    <p>Last name: <input data-bind='value: lastName' /></p> 
    <h2>Hello, <span data-bind='text: fullName'> </span>!</h2>  
</div>

//在我的索引(内容)页面中。

<div class='liveExample' id="sectionTwo">   
    <p>First name: <input data-bind='value: firstName' /></p> 
    <p>Last name: <input data-bind='value: lastName' /></p> 
    <h2>Hello, <span data-bind='text: fullName'> </span>!</h2>  
</div>

代码:

//在我的_Layout页面中: ko.applyBindings(new ViewModel1(“Planet”,“Earth”),$(“#sectionOne”)[0]); //这使得Knockout开始工作

//在我的索引页面中: ko.applyBindings(new ViewModel2(“Planet”,“Earth”),$(“#sectionTwo”)[0]); //这使得Knockout开始工作

这是一个jsfiddle

https://jsfiddle.net/4fe2f6mL/1/

我无法创建主视图模型,上面的两个模型作为子视图,因为ko.applyBindings位于单独的cshtml文件中。

我如何才能使这个工作,因为我有一个用于我的布局的视图模型(驱动菜单,登录,注册和导航栏中的“欢迎,用户名”类型的东西)

1 个答案:

答案 0 :(得分:1)

您链接的示例有效,因为数据绑定元素是兄弟。当有父子结构时,您无法轻松地将绑定到与不同的视图模型,仅使用{{ 1}}。

使用部分.cshtml文件和Razor做模板有时会与淘汰赛自己的模板功能发生冲突......就个人而言,我倾向于只在部分中定义淘汰赛templates并使用ko.applyBindingsforeach绑定以获取我的视图以进行渲染。

脏修复

现在快速而肮脏的修复可能是创建一个自定义绑定,禁用DOM树的一部分中的绑定:

&#13;
&#13;
with
&#13;
ko.bindingHandlers.stopBinds = {
  init: function() {
    return { controlsDescendantBindings: true }   
  }
}

ko.virtualElements.allowedBindings.stopBinds = true;

// In your main js you bind the parent
var parent = document.getElementById("parent");
ko.applyBindings({ test: "Parent value" }, parent);
&#13;
&#13;
&#13;

稍微好一些修复

&#13;
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<div id="parent">
    <p data-bind="text: test"></p>

    <!-- start of your partial: -->

    <!-- ko stopBinds -->
      <div id="child" >
        <p data-bind="text: test"></p>
      </div>  
      <script>
        var child = document.getElementById("child");
        ko.applyBindings({ test: "Child value" }, child);
      </script>
    <!-- /ko -->
  
    <!-- end of your partial -->
</div>
&#13;
ko.bindingHandlers.stopBinds = {
  init: function() {
    return { controlsDescendantBindings: true }   
  }
}

ko.virtualElements.allowedBindings.stopBinds = true;

// Expose the main vm
window.myVM = {
  test: "Parent value",
  childVM: ko.observable(null)
};

// Bind to document
$(document).ready(function() {
  ko.applyBindings(window.myVM);
  
  // Check if any callbacks have been registered and run them
  window.callbacks.forEach(function(cb) {
    cb();
  });
});
&#13;
&#13;
&#13;