表格标题中的复选框可检查其他行

时间:2015-06-17 04:47:30

标签: jquery knockout.js

我的表头中有一个复选框,用于选择/取消选中表中的所有复选框。我尝试将更改/单击事件绑定到该表。同一事件适用于其他复选框,但不适用于标题上的复选框。我正在使用MVC3& KnockoutJS绑定。在下面添加了代码部分。

<tr class="cont-subhead trClinicList">
    <th class="tWidth10 textAlign">
        <input type="checkbox" id="selectAllCb" data-bind="event:{ change:function(){$root.ClickSelectAll();return true;} }"  />
</tr>

jQuery的:

self.ClickSelectAll = function (data,event) {
    alert("method hit");
    if ($('#selectAllCb').is(':checked')) {
        for (var i = 0; i < self.AdminToolDetails().length; i++) {
            if (self.AdminToolDetails()[i].IsEnabled() && self.AdminToolDetails()[i].IsSelected() == false) {
                self.AdminToolDetails()[i].IsSelected(true);
            }
        }
    }

    else {
        for (var i = 0; i < self.AdminToolDetails().length; i++) {
            if (self.AdminToolDetails()[i].IsEnabled() && self.AdminToolDetails()[i].IsSelected()) {
                self.AdminToolDetails()[i].IsSelected(false);
            }
        }
    }
};

请告诉我如何处理表头输入的复选框事件。

1 个答案:

答案 0 :(得分:0)

糟糕! 不要混淆使用jQuery和Knockout操作DOM。使用KnockoutJS,尝试在视图模型上运行所有逻辑和更改,并让库处理视图中的更新/更新。 / p>

以下是使用KO执行此操作的方法:

var Item = function(name) {
  this.name = name;
  this.isSelected = ko.observable(false);
};

var Root = function() {
  var self = this;
  
  self.items = ko.observableArray([new Item("Abc"), new Item("Xyz")]);
  
  self.selectAll = ko.computed({
    read: function() { 
      return self.items().every(function(i) { return !!i.isSelected(); }) 
    },
    write: function(newVal) {
      self.items().forEach(function(i) { i.isSelected(newVal); });
    }
  });
};
                               
ko.applyBindings(new Root());
th { border-bottom: 1px solid gray; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<table>
  <thead>
    <tr class="cont-subhead trClinicList">
      <th>
          <input type="checkbox" data-bind="checked: selectAll" />
      </th>
      <th>Name</th>
    </tr>
  </thead>
  <tbody data-bind="foreach: items">
    <tr>
      <td class="tWidth10 textAlign">
          <input type="checkbox" data-bind="checked: isSelected" />
      </td>
      <td data-bind="text: name"></td>
    </tr>
  </tbody>
</table>

这个使用a writable computed observable,如果单个文本框被选中(de),它还允许您轻松更新复选框(视图)。

我在我的示例中选择了这种方法,因为您最初使用change事件。但是,如果您更喜欢使用单击处理程序,则可以按以下方式执行相同的操作:

var Item = function(name) {
  this.name = name;
  this.isSelected = ko.observable(false);
};

var Root = function() {
  var self = this;
  
  self.items = ko.observableArray([new Item("Abc"), new Item("Xyz")]);
  
  self.allSelected = ko.computed(function() { 
    return self.items().every(function(i) { return !!i.isSelected(); }) 
  });
  
  self.toggleAllSelected = function(viewModel, event) {
    var newVal = !self.allSelected();
    self.items().forEach(function(i) { i.isSelected(newVal); });
    return true; // So the browser won't also handle "click" and uncheck the input again
  };
};
                               
ko.applyBindings(new Root());
th { border-bottom: 1px solid gray; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<table>
  <thead>
    <tr class="cont-subhead trClinicList">
      <th>
          <input type="checkbox" data-bind="checked: allSelected, click: $root.toggleAllSelected" />
      </th>
      <th>Name</th>
    </tr>
  </thead>
  <tbody data-bind="foreach: items">
    <tr>
      <td class="tWidth10 textAlign">
          <input type="checkbox" data-bind="checked: isSelected" />
      </td>
      <td data-bind="text: name"></td>
    </tr>
  </tbody>
</table>

任何地方都不需要DOM操作,这完全由Knockout处理(这主要是为了它)。额外的好处:您的视图模型是高度可测试的(例如,为selectAll编写单元测试很容易等)。