javascript Knockout + MVC - 不能对同一个元素多次应用绑定
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18840173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Knockout + MVC - You cannot apply bindings multiple times to the same element
提问by RobVious
My MVC view:
我的 MVC 视图:
@model MG.ViewModels.Profile.ProfileDetailsViewModel
<div>
<h4>About Me</h4>
<!-- ko if: !isEditingAboutMe() -->
<p data-bind="text: aboutMe()">@Model.AboutMe</p>
@if (Model.CurrentUserCanEdit)
{
<a data-bind="click: editAboutMe">edit</a>
}
<!-- /ko -->
<!-- ko if: isEditingAboutMe() -->
@Html.TextBoxFor(model => model.AboutMe, new { data_bind = "value: aboutMe" })
<a data-bind="click: saveAboutMe">save</a>
<a data-bind="click: cancelAboutMe">cancel</a>
<!-- /ko -->
</div>
<script type="text/javascript">ko.applyBindings(@Html.Raw(Json.Encode(Model)));</script>
My ProfileVm Javascript:
我的 ProfileVm Javascript:
function ProfileVm() {
var self = this;
self.saveAboutMe = function() {
self.isEditingAboutMe(false);
};
self.cancelAboutMe = function() {
self.isEditingAboutMe(false);
};
self.isEditingAboutMe = ko.observable(false);
self.editAboutMe = function() {
self.isEditingAboutMe(true);
};
}
$(document).ready(function () {
ko.applyBindings(new ProfileVm());
})
I'm loading ProfileVm in Layout.cshtml via a bundle:
我正在通过一个包在 Layout.cshtml 中加载 ProfileVm:
@Scripts.Render("~/bundles/viewmodels")
I'm calling ko.applyBindings() twice - once directly in my view to bind the MVC Model to knockout observables, and the other to bind the properties of the ProfileVm.
我调用 ko.applyBindings() 两次 - 一次直接在我的视图中将 MVC 模型绑定到淘汰可观察对象,另一个绑定 ProfileVm 的属性。
What am I doing wrong?
我究竟做错了什么?
回答by RP Niemeyer
You should not call ko.applyBindingson the same elements more than once, as it will potentially add multiple event handlers to the same elements and/or bind different data to the elements. In KO 2.3, this now throws an exception.
您不应ko.applyBindings多次调用相同的元素,因为它可能会向相同的元素添加多个事件处理程序和/或将不同的数据绑定到元素。在 KO 2.3 中,这会引发异常。
ko.applyBindingsdoes accept a second argument that indicates the root element to use in binding.
ko.applyBindings确实接受指示要在绑定中使用的根元素的第二个参数。
So, it is possible to do something like:
因此,可以执行以下操作:
<div id="left">
....
</div>
<div id="right">
....
</div>
Then, you would bind like:
然后,你会像这样绑定:
ko.applyBindings(leftViewModel, document.getElementById("left"));
ko.applyBindings(rightViewModel, document.getElementById("right"));
If you have a scenario where the elements actually overlap, then you would have to do something like this: http://www.knockmeout.net/2012/05/quick-tip-skip-binding.html
如果你有一个元素实际上重叠的场景,那么你必须做这样的事情:http: //www.knockmeout.net/2012/05/quick-tip-skip-binding.html
回答by Michael Best
@RPNiemeyer has provided an excellent explanation of the problem. But I think that instead of trying to apply two view models, the simpler solution is to combine your view models into one. Something like this:
@RPNiemeyer 对这个问题提供了很好的解释。但我认为与其尝试应用两个视图模型,更简单的解决方案是将您的视图模型合二为一。像这样的东西:
function ProfileVm(model) {
var self = this;
self.aboutMe = ko.observable(model.AboutMe);
self.saveAboutMe = function() {
self.isEditingAboutMe(false);
};
self.cancelAboutMe = function() {
self.isEditingAboutMe(false);
};
self.isEditingAboutMe = ko.observable(false);
self.editAboutMe = function() {
self.isEditingAboutMe(true);
};
}
$(document).ready(function () {
ko.applyBindings(new ProfileVm(@Html.Raw(Json.Encode(Model))));
})

