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.applyBindings
on 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.applyBindings
does 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))));
})