knockout.js访问包含的viewModel中的容器模型属性

时间:2013-09-26 04:47:13

标签: javascript knockout.js

我有嵌套的视图模型,如下所示。我试图从包含的视图模型(子)访问容器视图模型中的值。当modelA.prop1试图获取mainVM.prop1值时,我得到了未定义的错误。谢谢你的帮助。

function mainVM() {

    var self = this;

    //chain associated view models
    self.modelA = new modelA();
    self.modelB = new modelB();

    self.prop1 = ko.observable("some value from mainVM.prop1");

}
function modelA(){
   var self = this;
   self.prop1 = ko.observable(mainVM.prop1); //I'd like to get value in containing view model above
}
function modelB(){....}

$(function () {
    var viewModel = new mainVM();
    ko.applyBindings(viewModel);
});

3 个答案:

答案 0 :(得分:1)

如果您想让子ViewModel依赖/了解他们的父级,您必须将它传递给他们。 E.g:

function mainVM() {
    var self = this;

    //chain associated view models
    self.modelA = new modelA(self);
    self.modelB = new modelB(self);

    self.prop1 = ko.observable("some value from mainVM.prop1");

}
function modelA(parent){
   var self = this;
   self.prop1 = ko.observable(parent.prop1); //I'd like to get value in containing view model above
}
function modelB(parent){....}

$(function () {
    var viewModel = new mainVM();
    ko.applyBindings(viewModel);
});

请仔细考虑,如果您的设计中存在这种依赖性。

另一种解决方案(尽管从设计的角度来看可能更糟)解决方案是让他们通过范围进行访问,例如:

$(function () {
    function mainVM() {
        var self = this;

        //chain associated view models
        self.modelA = new modelA();
        self.modelB = new modelB();

        self.prop1 = ko.observable("some value from mainVM.prop1");

    }
    function modelA(){
       var self = this;
       self.prop1 = ko.observable(viewModel.prop1); //I'd like to get value in containing view model above
    }
    function modelB(){....}

    var viewModel = new mainVM();
    ko.applyBindings(viewModel);
});

答案 1 :(得分:0)

@Jeroen的一些额外想法回答

依赖于来自子级的父级不仅设计糟糕,而且很难找到内存泄漏

如果您使用来自子计算机中的父项,KO将挂钩一个依赖项,如果您删除该子项,它的计算结果仍会在父项更改状态时触发。

我解决模型之间依赖关系的一般方法是使用EventAggregator模式,我已为此库创建了一个模式

https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy

它是一个signalR库,如果你不需要singalR,你可以提取事件聚合部分

演示 http://jsfiddle.net/jh8JV/

ViewModel = function() {
    this.events = ko.observableArray();
    this.subModel = new SubViewModel();

    signalR.eventAggregator.subscribe(Event, this.onEvent, this);
};

ViewModel.prototype = {
    onEvent: function(e) {
        this.events.push(e);
    }
};

答案 2 :(得分:0)

我认为你在这里遇到了“XY问题”:你想要完成任务X(你还没有在这里命名),你认为实现Y(在这种情况下,是一个依赖于它的子VM)父母)是这样做的方式,即使Y可能不是最佳(甚至是好的)方式。

您尝试解决的实际问题是什么?如果你需要从子绑定中访问父属性,Knockout的绑定上下文($ root,$ parent,$ parents []等)将允许你这样做,例如。

<div data-bind="with:modelA">
   <p>prop2 is <span data-bind="text:prop2"></span>
      and prop1 from the main model is
      <span data-bind="text:$root.prop1"></span>
   </p>
</div>

在这种情况下,您可以使用$parent代替$root,因为只有一个级别的嵌套。