【问题标题】:Knockout, select all checkboxes and view list of select checkboxes淘汰赛,选中所有复选框并查看选中复选框列表
【发布时间】:2015-03-27 17:45:18
【问题描述】:

我有一个带有复选框的列表,当我单击其中一个时,它会显示在SelectedUsers 中,可以正常工作,并且复选框data-bind="checked: AllChecked" 也会被选中,但它不应该被选中。

<div data-bind="foreach: SelectedUsers">
    <p>
        <span data-bind="text: userName" ></span>
    </p>
</div>

但是,当我使用data-bind="checked: AllChecked" 时,SelectedUsers 中没有显示任何内容,之后,当我单击某个复选框时,列表中的所有项目都被选中,SelectedUsers 中没有任何显示

怎么了? 例如:http://jsfiddle.net/falkone/cr763bfj/

<div id="sideB">
    <div data-bind="foreach: AllUsers">
        <label>
            <input type="checkbox" name="checkedUser" data-bind="value: userName, checked:$root.selectedUserNames" />
            <span data-bind="text: userName" ></span>
        </label> 
    </div>
    Selected
    <div data-bind="foreach: SelectedUsers">
        <p>
            <span data-bind="text: userName" ></span>
        </p>
    </div>
        <label><input type="checkbox" data-bind="checked: AllChecked" />Check all</label>
</div>

淘汰赛-3.3.0:

function User(data) {
this.userName = ko.observable(data.userName);
this.selected = ko.observable(data.selected);

}

var dataSource = [new User({userName: "Bill", selected: false}),
    new User({userName: "Andrii", selected: false})
    ];

function UsersViewModel() {
    var self = this;
    self.AllUsers = ko.observableArray(dataSource);
    self.SelectedUsers = ko.observableArray([]);

self.selectedUserNames = ko.observableArray([]);

self.selectedUserNames.subscribe(function(newValue) {
    var newSelectedUserNames = newValue;
    var newSelectedUsers = [];
    ko.utils.arrayForEach(newSelectedUserNames, function(userName) {
        var selectedUser = ko.utils.arrayFirst(self.AllUsers(), function(user) {
            return (user.userName() === userName);
        });
        newSelectedUsers.push(selectedUser);
    });
    self.SelectedUsers(newSelectedUsers);
});

self.AllChecked = ko.computed({
    read: function() {
        var firstUnchecked = ko.utils.arrayFirst(dataSource, function(item) {
            return self.selectedUserNames() == false;
        });
        return firstUnchecked == null;
    },
    write: function(value) {
        ko.utils.arrayForEach(dataSource, function(item) {
            self.selectedUserNames(value);
        });
    }
})
}

ko.applyBindings(new UsersViewModel(), document.getElementById('sideB'));

【问题讨论】:

    标签: list checkbox knockout.js


    【解决方案1】:

    在调用write 时传递给computed 的值不是用户名,而是一个true / false 布尔值,表示复选框状态。

    另外,由于selectUserNamesobservableArray,您需要将push() 替换为新的userName,而不是替换整个数组数据。

    试试这个:

    read: function() {
            var firstUnchecked = ko.utils.arrayFirst(dataSource, function(item) {
                return self.selectedUserNames().indexOf(item.userName()) == -1;
            });
            return firstUnchecked == null;
        },
    write: function(value) {
            if (value) {
                ko.utils.arrayForEach(dataSource, function(item) {
                   if (self.selectedUserNames().indexOf(item.userName()) == -1)
                       self.selectedUserNames.push(item.userName());
                });
            }
            else {
                self.selectedUserNames.removeAll();
            }
        }
    

    更新(根据您的评论):

    还需要更改read 以使用indexOf 检查第一个未检查的userName 是否存在:

    var firstUnchecked = ko.utils.arrayFirst(dataSource, function(item) {
        return self.selectedUserNames().indexOf(item.userName()) == -1;
    });
    

    查看修改后的Fiddle

    【讨论】:

    • 它有效,谢谢。为什么当我单击其中一个复选框时, data-bind="checked: AllChecked" 也被选中,它不应该是这样的。
    • 只有在所有ckckbox都被选中时才应该被选中
    • 感谢您的帮助,但我还有一个问题。当我选择其中一项然后选择“全选”时,我之前选择的项目在列表中重复,我该如何更正?
    • jsfiddle.net/cr763bfj/5。我实际上在pushing 之前添加了if (self.selectedUserNames().indexOf(item.userName()) == -1)
    • 感谢您的帮助!
    猜你喜欢
    • 2020-08-28
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 2013-03-11
    • 2013-08-06
    相关资源
    最近更新 更多