首页 文章

Knockout MVC - 您不能多次将绑定应用于同一元素

提问于
浏览
2

我的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>

我的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());
})

我正在通过捆绑包在Layout.cshtml中加载ProfileVm:

@Scripts.Render("~/bundles/viewmodels")

我正在调用ko.applyBindings()两次 - 一次直接在我看来将MVC模型绑定到knockout observables,另一次绑定ProfileVm的属性 .

我究竟做错了什么?

2 回答

  • 2

    @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))));
    })
    
  • 7

    您不应多次对相同的元素调用 ko.applyBindings ,因为它可能会将多个事件处理程序添加到相同的元素和/或将不同的数据绑定到元素 . 在KO 2.3中,现在抛出异常 .

    ko.applyBindings 确实接受第二个参数,该参数指示要在绑定中使用的根元素 .

    所以,有可能做类似的事情:

    <div id="left">
       ....
    </div>
    
    <div id="right">
       ....
    </div>
    

    然后,你会绑定像:

    ko.applyBindings(leftViewModel, document.getElementById("left"));
    ko.applyBindings(rightViewModel, document.getElementById("right"));
    

    如果你有一个场景,其中元素实际重叠,那么你必须做这样的事情:http://www.knockmeout.net/2012/05/quick-tip-skip-binding.html

相关问题