0

我有一个jsfiddle来大致说明我在应用程序代码中遇到的情况。(为了后代,我将在下面发布实际的小提琴代码。)

本质上,我有一个可观察的数组,用于填充复选框选项列表。选择其中一个选项将该项目添加到另一个仅由所选项目组成的可观察数组中。

如果表单中有一些错误(或者我想如果您正在编辑现有数据),则从一开始就使用先前选择的项目填充选定的 observable 数组。但是,现在,原始项目和选定项目之间没有任何联系,因此选中或取消选中其中一个复选框会添加重复项,并且只会删除该重复项。

我的问题是 1)我是否完全错了(即有没有更好的方法来做到这一点不会导致这个问题)和 2)如果没有,恢复项目之间连接的最佳方法是什么,以便复选框将指示项目在那里,取消选中它们将删除项目?

HTML

<ul data-bind="foreach: Fruit">
    <li>
        <label>
            <input type="checkbox" class="cbFruit" data-bind="checked: Selected, attr: { value: Name }" />
            <span data-bind="text: Name"></span>
        </label>
    </li>
</ul>

<ul data-bind="foreach: SelectedFruit">
    <li data-bind="text: Name"></li>
</ul>

JS

var FruitViewModel = function (name) {
    var self = this;

    self.Name = ko.observable(name);
    self.Selected = ko.observable(false);

    return self;
};

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

    self.Fruit = ko.observableArray([
        new FruitViewModel('Apples'),
        new FruitViewModel('Oranges'),
        new FruitViewModel('Bananas'),
        new FruitViewModel('Pineapples')
    ]);

    self.SelectedFruit = ko.observableArray([
        new FruitViewModel('Oranges'),
        new FruitViewModel('Bananas')
    ]);

    return self;
};

$(document).ready(function () {
    var viewModel = GroceryStoreViewModel();
    ko.applyBindings(viewModel);

    $('.cbFruit').on('click', function () {
        var fruit = ko.dataFor(this);
        if (fruit.Selected()) {
            viewModel.SelectedFruit.push(fruit);
        } else {
            viewModel.SelectedFruit.remove(fruit);
        }
    });
});
4

1 回答 1

0

我通过简单地丢弃单独的可观察数组(和单独的发布列表)解决了这个问题。相反,我对两种foreach用途都使用相同的完整列表,而在第二种用途中,使用 Knockout 虚拟if元素,让它只显示选定的:

HTML

<ul data-bind="foreach: Fruit">
    <li>
        <label>
            <input type="checkbox" class="cbFruit" data-bind="checked: Selected, attr: { value: Name }" />
            <span data-bind="text: Name"></span>
        </label>
    </li>
</ul>

<ul data-bind="foreach: Fruit">
    <!-- ko if: Selected -->
    <li data-bind="text: Name"></li>
    <!-- /ko -->
</ul>

第二个列表中的数据与第一个一起发布,因此我必须在服务器端进行一些清理工作,以确保在再次显示视图时返回纯内容值(水果名称等)。

于 2013-05-03T14:31:22.397 回答