0

我有嵌套的视图模型,如下所示。我正在尝试从包含的视图模型(子)访问容器视图模型中的值。当 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);
});
4

3 回答 3

1

如果您想让子 ViewModel 依赖/了解它们的父级,则必须将其传递给它们。例如:

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);
});
于 2013-09-26T06:19:50.820 回答
0

我认为您在这里遇到了“XY 问题”:您想要完成任务 X(您没有在此处命名)并且您认为实现 Y(在这种情况下,子虚拟机依赖于其父虚拟机)是做到这一点的方法,即使 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因为只有一层嵌套。

于 2013-09-27T21:23:29.707 回答
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);
    }
};
于 2013-09-26T07:53:50.330 回答