2

我有一系列复选框,它们都绑定到一组选定值:

var myModel = {
   // ...
   workgroupsImpacted: ko.observableArray([])
};

在顶部,我有一个全选复选框。选中全选复选框后,我运行以下代码:

var subGroups = $('#WorkgroupCB_' + parentId);
$(':input', subGroups).prop('checked', this.checked);

这将选中(或取消选中)相应的复选框控件。这很好用,UI 明智,但是绑定模型没有得到更新。换句话说,workgroupsImpacted仍然是空的。

当我选中取消选中一堆复选框时,是否有一种简单的方法来更新模型?或者,我是否必须遍历每个复选框,挖掘值,然后从模型中的数组中手动​​添加或删除该值?我希望 Knockout.js 提供一个标准的机制来轻松地做到这一点。

4

4 回答 4

2

KnockoutJS中,它observable array只是跟踪数组中的项目数量并报告更改(即添加/删除项目),但它不跟踪该数组中对象的状态。

听起来你想要一个observable arrayof observables。你有代表checkbox列表中每个的模型对象吗?

这是一个小提琴,它显示了observable array.

于 2013-07-09T20:16:21.733 回答
1

你不应该使用 jquery 来做到这一点。

您应该只有一个代表复选框的模型,其中包含一个代表复选框状态的 ko.observable。要检查所有内容,您只需遍历复选框并将 ko.observable 更改为 true。

于 2013-07-09T20:20:21.307 回答
1

您应该创建一个可写的计算 observable 来表示您的“全选”复选框。这是一个例子:

this.allItemsSelected = ko.computed({
    read: function() {
        return this.selectedItems().length === this.items().length;
    },
    write: function(value) {
        this.selectedItems(value ? this.items.slice(0) : [] );
    },
    owner: this
});

我已经写了一个类似问题的答案,其中更详细地介绍了上述示例,包括这个 jsFiddle:http: //jsfiddle.net/mbest/L3LeD/

在 write 函数中,如果你想用每个项目的属性填充你选择的项目数组,你可以使用这个:

this.selectedItems(value ?
    ko.utils.arrayMap(this.items(), function(item) { return item.property; }) :
    [] );
于 2013-07-09T20:52:39.850 回答
1

我了解您不想维护模型中的项目列表。在 Knockout 中仍然可以处理这种情况,方法是使用自定义绑定。

这是我整理的一个,它将使用更新复选框click(因为这是 Knockout 所关注的)。为了确保“全选”复选框是最新的,它会监视数组的更改(只需在update函数中访问它),然后只查找任何未选中的复选框。

ko.bindingHandlers.allChecked = {
    init: function(element, valueAccessor) {
        $(element).click(function() {
            $(valueAccessor().selector)
                .filter(element.checked ? ':not(:checked)' : ':checked')
                .click();
        });
    },
    update: function(element, valueAccessor) {
        var value = valueAccessor(),
            watch = ko.unwrap(value.watch),
            unchecked = $(value.selector).filter(':not(:checked)');
        element.checked = (unchecked.length === 0);
    }
};

将它绑定到一个复选框输入元素,如下所示:

<input type="checkbox" data-bind="
    allChecked: {
        selector: '#checks input:checkbox', 
        watch: selectedItems}" />

jsFiddle:http: //jsfiddle.net/mbest/nth7A/

于 2013-07-10T01:43:27.603 回答