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

标签 javascript jquery html knockout.js

我有一个 MVC 应用程序,它有一个链接到 View 模型的内容页面。效果很好。但是,一旦我将 View 模型添加到我的内容页面(在我的布局中生成),我就会收到错误:

You cannot apply bindings multiple times to the same element.

我已经创建了“部分”并尝试绑定(bind)到该部分,如下所示。

//在我的布局页面中。

<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("行星", "地球"), $("#sectionOne")[0]);//这使得 knockout 开始工作

//在我的索引页面中: ko.applyBindings(new ViewModel2("行星", "地球"), $("#sectionTwo")[0]);//这使得 knockout 开始工作

这是一个jsfiddle

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

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

我怎样才能让它工作,因为我的布局有一个 View 模型(驱动菜单、登录、注册和导航栏中的“欢迎,用户名”类型的内容)

最佳答案

您链接的示例之所以有效,是因为数据绑定(bind)元素是同级。当存在父子结构时,您无法仅使用ko将绑定(bind)到与不同的 View 模型。应用绑定(bind)

使用部分.cshtml文件和Razor进行模板有时会与knockout自己的模板功能发生冲突...就我个人而言,我倾向于只定义knout templates在部分中并使用 foreachwith 绑定(bind)来渲染我的 View 。

脏修复

目前一个快速而肮脏的修复方法可能是创建一个自定义绑定(bind)来禁用 DOM 树的一部分中的绑定(bind):

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

稍微好一点的修复

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();
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<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: -->
      <div id="child" data-bind="with: childVM">
        <p data-bind="text: test"></p>
      </div>  
      <script>
          // Register a callback
          window.callbacks = window.callbacks || [];
          window.callbacks.push(function() {
            window.myVM.childVM({ test: "Child value" });
          });
      </script>
    <!-- end of your partial -->
</div>

关于javascript - 两个单独的模型 - 您不能将绑定(bind)多次应用于同一元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40716526/

相关文章:

javascript - 是否可以在窗口大小更改时自动更改组元素的大小?

javascript - 在文本区域中设置 JSON 格式

javascript - 当用户尝试滚动时禁用滚动但仍然跟踪

javascript - 如何在 Select2.js 上基于其他 <select> 禁用 <select>

javascript - 当点击 1 然后谷歌地图不显示

javascript - 定位外部网页中的输入框

javascript - 在 html5 中围绕中心轴旋转内容

javascript - 通过添加 html 标签重新格式化文本

javascript - 使用 JS 滚动时固定表头

javascript - jQuery Framework 用于将评论附加到图像,例如 Facebook 或 Flickr