从子视图模型修改父亲的敲除可观察模式

我有一个父子视图模型对象结构,并且需要更新子视图的父视图。 我基本上想出了两种模式:

1]将父属性的引用传递给子代并从子代内更新属性:

var ParentViewModel = function(){
    var self = this;
    this.selectedItem = ko.observable();
    this.child = ko.observable(new ChildViewModel(self.selectedItem));
}

var ChildViewModel = function(parentSelectedItem){
    var self = this;
    this.id = ko.observable();
    this.parentSelectedItem = parentSelectedItem;
    this.select = function(){
        self.parentSelectedItem(self);
    }
}

2]在父级上创建子级的select方法,并在本地引用父级observable。

var ParentViewModel = function(){
    var self = this;
    this.selectedItem = ko.observable();

    var child = new ChildViewModel();
    child.select = function(){
        self.selectedItem(child);
    }
    this.child = ko.observable(child);
}

var ChildViewModel = function(){
    this.id = ko.observable();
}

这些模式都没有让我感到高兴。 第一个将整个属性引用推入到子视图模型中,第二个定义了子范围之外的子函数。

有没有人有任何其他模式的建议,如何在JavaScript中以干净和可测试的方式实现此操作? 或者我或多或少地陷入了这两种选择?


在Knockout中最常见的模式是在你的父母身上放置一个“selectChild”方法来接收孩子。 在大多数情况下,实际的孩子不需要知道它被选中。

然后在绑定中,您可以绑定到$root.selectChild$parent.selectChild 。 传递给绑定到click / event绑定的处理程序的第一个参数是实际数据(在KO 2.0中),因此您的方法可以在父级上生存,并接收子级作为第一个arg。

var Item = function(id, name) {
    this.id = id;
    this.name = ko.observable(name);    
};

var ViewModel = function() {
    var self = this;
    this.items = ko.observableArray([
        new Item(1, "one"),
        new Item(2, "two"),
        new Item(3, "three")
    ]);  

    this.selectedItem = ko.observable();

    this.selectItem = function(item) {
        self.selectedItem(item);
    };     
};

在这种情况下,您的绑定将如下所示:

<ul data-bind="foreach: items">
    <li>
        <a href="#" data-bind="text: name, click: $root.selectItem"></a>
    </li>
</ul>

这里是在jsFiddle:http://jsfiddle.net/rniemeyer/anRsA/

你甚至可以进一步简化它。 Observable是函数,你传递给它们的第一个参数用于设置它们的值,所以你甚至可以选择不包含selectItem方法,直接直接绑定到$root.selectedItem (看起来像:http:// jsfiddle。净/ rniemeyer / anRsA / 1 /)。 我通常使用一个单独的方法来明确,给它一个合适的名字(动作),以及在设置项目之前或之后需要进行额外处理的情况。

在KO 2.0之前(其中引入了$root$parent以及将数据作为第一个参数传递给clickevent处理程序的更改),我曾经使用第一种方法,您提出了相当多的建议。 你可以在那里做的一件事实际上并不是创建子属性( this.parentSelectedItem ),而是直接在select方法中引用parentSelectedItem (它作为参数传递),因为它可以在函数中使用,因为封闭被建造。

链接地址: http://www.djcxy.com/p/8833.html

上一篇: Pattern for modifying knockout observable on parent from child view model

下一篇: Combining inheritance with the module pattern