List 取消选中,选中所有复选框并查看选中复选框列表

List 取消选中,选中所有复选框并查看选中复选框列表,list,checkbox,knockout.js,List,Checkbox,Knockout.js,我有一个带有复选框的列表,当我单击其中一个复选框时,它会显示在SelectedUsers中,并按其应该的方式工作,复选框data bind=“checked:AllChecked”也会被选中,但不应该被选中 <div data-bind="foreach: SelectedUsers"> <p> <span data-bind="text: userName" ></span> </p> </div

我有一个带有复选框的列表,当我单击其中一个复选框时,它会显示在
SelectedUsers
中,并按其应该的方式工作,复选框
data bind=“checked:AllChecked”
也会被选中,但不应该被选中

<div data-bind="foreach: SelectedUsers">
    <p>
        <span data-bind="text: userName" ></span>
    </p>
</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'));

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

另外,由于
selectUserNames
是一个
observearray
,因此需要
push()
新的
用户名
,而不是替换整个数组数据

请尝试以下方法:

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();
        }
    }
更新(根据您的评论):

还需要更改读取的
以使用
indexOf
检查是否存在第一个未选中的
userName

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

请参见修改后的

它可以工作,谢谢。为什么当我点击其中一个复选框时,data bind=“checked:AllChecked”也被选中,它不应该是这样的。只有当所有复选框都被选中时才应该被选中谢谢你的帮助,但我还有一个问题要问。当我选择其中一个项目,然后选择“全选”时,我在列表中重复之前选择的项目,如何更正此问题?请参阅。在实际推送之前,我添加了
if(self.selectedUserNames().indexOf(item.userName())==-1)
。感谢您的帮助!
var firstUnchecked = ko.utils.arrayFirst(dataSource, function(item) {
    return self.selectedUserNames().indexOf(item.userName()) == -1;
});