Knockout.js - 如何在单击所选项目时取消选中可用项目observable

时间:2017-02-11 02:19:25

标签: javascript ajax arraylist knockout.js

单击顶部列表中的元素时进行选择。单击底部元素时,将从列表中删除它。但是,顶部列表中的复选框不是false。我该如何解决呢?

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>

1 个答案:

答案 0 :(得分:0)

我有一段时间没有使用Knockout.js,但看起来您的问题是remove()方法正在从SelectedUsers observable中移除用户,当您实际应该删除用户名时来自selectedUserNames observable而不是。

根据您设置绑定的方式,您订阅了selectedUserNames observable并更新了此订阅中的SelectedUsers observable。这意味着当您从SelectedUsers observable中删除用户时未调用订阅,这解释了为什么在删除用户名时没有看到相应的用户取消选中。

换句话说,更改以下方法:

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

改为:

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

以下是包含完整代码的更新示例:

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>