Knockout.js和复选框的双向绑定

时间:2012-06-13 07:53:10

标签: javascript knockout.js

首先:我是淘汰js的新手,并试图围绕淘汰/ mvvm的思维方式,所以如果我的问题变得微不足道,请原谅我。

我所拥有的是以下情况:我有一个淘汰视图模型,其中包含所选票证对象的observableArray。此数组表示用户定义的更大票数集的选择/子集。整个票证集列在jqgrid表中,每行都有一个复选框,该复选框应该告诉您是否选择了每个票证。这意味着只要“selectedTickets”数组发生更改,就需要更新复选框的值。除此之外,我还希望用户能够单击每个复选框,以便从选择中添加/删除票证。看起来似乎是一个相当可接受的功能,对吗?

然而,我确实无法看到如何使用敲击“已检查”绑定来实现此目的。我的第一个想法是在名为“isSelected”的viewmodel对象上使用计算/从属observable,它将反映selectedTickets数组中的更改,并根据票证是否在selectedTickets数组中返回true或false。这里的第一个问题是,我需要将一个参数传递给计算的observable,说明它应该查找哪个票证ID,以及我可以看到的只能在可写的计算可观察量上工作。然而,获取复选框的状态看起来不像是写操作,因此已经开始闻到一些东西。下一个问题是绑定需要双向,因为我希望用户能够更改每个复选框的状态并相应地更新selectedTickets数组。这是一个不同的操作,因为它实际上会删除/添加selectedTickets数组的票证。这将再次触发计算的observable尝试设置复选框的状态。似乎这两个用例可能最终会像无限循环一样,如果我尝试这样做的话。我没有找到一种很好的方法来组合这两个用例,只需使用选中的复选框即可。

我当然可以手动对复选框进行事件处理,通过将侦听器连接到复选框上的已更改事件以及knockout视图模型中的selectedTickets数组,但我希望这可以通过敲除绑定更自动化

希望有一些淘汰赛大师可以指导我走上一条好路,因为我觉得我已经偏离了这条赛道。

1 个答案:

答案 0 :(得分:6)

使用knockout.js时,你需要停止一半的事情 - 如果你有一个项目列表,数据属于viewmodel(不仅仅是选择项目),只有视图定义了外观。

因此,我建议使用items类型的可观察数组Item,它具有属性isSelected - 然后可以通过计算的observable访问所选项:

var Item = function(name) {
    this.name = ko.observable(name);
    this.isSelected = ko.observable(false);
};

var ViewModel = function() {
    var self = this;

    self.items = ko.observableArray([
        new Item('Foo'), new Item('Bar'), new Item('Foo Bar')
    ]);

    self.selectedItems = ko.computed(function() {
        return ko.utils.arrayFilter(self.items(), function(item) {
            return item.isSelected();
        });
    });
};

http://jsfiddle.net/htZfX/