简体   繁体   中英

Knockout.js - How to uncheck available item observable when clicking selected item

The selection is made when the elements in the top list are clicked. When you click on the bottom elements, it is deleted from the list. However, the checkbox on the top list was not false. How can I fix it.

 function User(data) { this.userName = ko.observable(data.userName); this.selected = ko.observable(data.selected); } var dataSource = [ new User({ userName: "test1", selected: false }), new User({ userName: "test2", selected: false }) ]; function UsersViewModel() { var self = this; //initial data may have two IEnumerables self.AllUsers = ko.observableArray(dataSource); self.SelectedUsers = ko.observableArray([]); self.selectedUserNames = ko.observableArray([]); remove: function myfunction() { SelectedUsers().remove(this); } 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.remove = function(e) { self.SelectedUsers.remove(e); } } ko.applyBindings(new UsersViewModel()); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> Available <ul data-bind="foreach: AllUsers, visible: AllUsers().length > 0"> <li> <!--<div data-bind="click: $parent.SelectedUser">--> <input type="checkbox" name="checkedUser" data-bind="value: userName, checked: $root.selectedUserNames" /> <span data-bind="text: userName"></span> <!--</div>--> </li> </ul> <br />Selected <ul data-bind="foreach: SelectedUsers, visible: SelectedUsers().length > 0"> <li data-bind="click: $parent.remove"> <span data-bind="text: userName"></span> </li> </ul> 

I haven't used Knockout.js in a while, but it looks like your problem is that the remove() method is removing users from the SelectedUsers observable, when you should actually be removing user names from the selectedUserNames observable instead.

Based on the way you have the binding set up, you are subscribing to the selectedUserNames observable and updating the SelectedUsers observable within this subscription. That means that the subscription wasn't being called when you were removing users from the SelectedUsers observable, which explains why you weren't seeing the corresponding user get unchecked when removing a username.

In other words, change the following method:

self.remove = function(e) {
  self.SelectedUsers.remove(e);
}

to this instead:

self.remove = function(e) {
  self.selectedUserNames.remove(e.userName());
}

Here is an updated example with your full code:

 function User(data) { this.userName = ko.observable(data.userName); this.selected = ko.observable(data.selected); } var dataSource = [ new User({ userName: "test1", selected: false }), new User({ userName: "test2", selected: false }) ]; function UsersViewModel() { var self = this; //initial data may have two IEnumerables 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.remove = function(e) { self.selectedUserNames.remove(e.userName()); } } ko.applyBindings(new UsersViewModel()); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> Available <ul data-bind="foreach: AllUsers, visible: AllUsers().length > 0"> <li> <!--<div data-bind="click: $parent.SelectedUser">--> <input type="checkbox" name="checkedUser" data-bind="value: userName, checked: $root.selectedUserNames" /> <span data-bind="text: userName"></span> <!--</div>--> </li> </ul> <br />Selected <ul data-bind="foreach: SelectedUsers, visible: SelectedUsers().length > 0"> <li data-bind="click: $parent.remove"> <span data-bind="text: userName"></span> </li> </ul> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM