两个独立的模型 - 您不能将绑定多次应用于同一个元素
Posted
技术标签:
【中文标题】两个独立的模型 - 您不能将绑定多次应用于同一个元素【英文标题】:Two separate models - You cannot apply bindings multiple times to the same element 【发布时间】:2017-04-04 15:11:30 【问题描述】:我有一个 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 文件中。
我怎样才能让它工作,因为我的布局有一个视图模型(在导航栏中驱动菜单、登录、注册和“欢迎,用户名”类型的东西)
【问题讨论】:
我不确定您面临什么问题,但我已经在没有 jquery 的情况下更新了您的 jsfiddle 并且结果正常:jsfiddle.net/Salmin/7tozbtj8/1 【参考方案1】:您链接的示例有效,因为数据绑定元素是兄弟。当存在 parent-child 结构时,您无法轻松地将 child 绑定到与 parent 不同的视图模型,仅使用 ko.applyBindings
。
使用部分 .cshtml 文件和 Razor 进行模板有时会与 Knockout 自己的模板功能发生冲突...就个人而言,我倾向于只在部分中定义 Knockout templates 并使用 foreach
和 with
绑定来获取我的要渲染的视图。
脏修复
目前一个快速而肮脏的修复方法可能是创建一个自定义绑定,在 DOM 树的一部分中禁用绑定:
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>
【讨论】:
谢谢。那么布局部分会是一个模板,而其余部分 - 正常吗?还是说每个视图模型都属于一个模板?在整个应用程序中。以上是关于两个独立的模型 - 您不能将绑定多次应用于同一个元素的主要内容,如果未能解决你的问题,请参考以下文章
Knockout.js v2.3.0 错误“您不能将绑定多次应用于同一元素”