如何应对在AngularJS指令上复选框的点击? [英] How to respond to clicks on a checkbox in an AngularJS directive?

查看:133
本文介绍了如何应对在AngularJS指令上复选框的点击?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个AngularJS 指令呈现实体在以下模板的集合:

I have an AngularJS directive that renders a collection of entities in the following template:

<table class="table">
  <thead>
    <tr>
      <th><input type="checkbox" ng-click="selectAll()"></th>
      <th>Title</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="e in entities">
      <td><input type="checkbox" name="selected" ng-click="updateSelection($event, e.id)"></td>
      <td>{{e.title}}</td>
    </tr>
  </tbody>
</table>

正如你所看到的,这是一个&LT;表&gt; ,其中的每一行都可以单独拥有自己的复选框被选中,或所有行可以一次选择与主复选框位于&LT;&THEAD GT; 。 pretty经典的UI。

As you can see, it's a <table> where each row can be selected individually with its own checkbox, or all rows can be selected at once with a master checkbox located in the <thead>. Pretty classic UI.

什么是最好的方式:


  • 选择单行(即当复选框被选中,所选实体的ID添加到内部数组中,并添加一个CSS类的&LT; TR&GT; 包含实体,以反映其选中状态)?

  • 在一次选择的所有行? (即做pviously描述的动作为所有行$ P $的&LT;表&gt;

  • Select a single row (i.e. when the checkbox is checked, add the id of the selected entity to an internal array, and add a CSS class to the <tr> containing the entity to reflect its selected state)?
  • Select all rows at once? (i.e. do the previously described actions for all rows in the <table>)

我目前的实现是一个自定义控制器添加到我的指令:

My current implementation is to add a custom controller to my directive:

controller: function($scope) {

    // Array of currently selected IDs.
    var selected = $scope.selected = [];

    // Update the selection when a checkbox is clicked.
    $scope.updateSelection = function($event, id) {

        var checkbox = $event.target;
        var action = (checkbox.checked ? 'add' : 'remove');
        if (action == 'add' & selected.indexOf(id) == -1) selected.push(id);
        if (action == 'remove' && selected.indexOf(id) != -1) selected.splice(selected.indexOf(id), 1);

        // Highlight selected row. HOW??
        // $(checkbox).parents('tr').addClass('selected_row', checkbox.checked);
    };

    // Check (or uncheck) all checkboxes.
    $scope.selectAll = function() {
        // Iterate on all checkboxes and call updateSelection() on them??
    };
}

更具体地讲,我不知道:

More specifically, I wonder:


  • 是否code在控制器上面属于或它应该在链接去功能?

  • 由于jQuery是不一定present(AngularJS并不需要它),什么是应该做DOM遍历的最佳方式?没有jQuery的,我有一个很难只选择父&LT; TR&GT;一个给定的复选框,或在模板中选择所有的复选框

  • 传递 $事件 updateSelection()似乎并不很优雅。是不是有更好的方法来检索元素的状态(选中/取消),这是刚刚点击?

  • Does the code above belong in a controller or should it go in a link function?
  • Given that jQuery is not necessarily present (AngularJS doesn't require it), what's the best way to do DOM traversal? Without jQuery, I'm having a hard time just selecting the parent <tr> of a given checkbox, or selecting all checkboxes in the template.
  • Passing $event to updateSelection() doesn't seem very elegant. Isn't there a better way to retrieve the state (checked/unchecked) of an element that was just clicked?

感谢您。

推荐答案

这是我一直在做这样的东西的方式。角倾向于支持DOM的,而不是一个当务之急一(至少这是我一直在玩的方式)的声明操纵。

This is the way I've been doing this sort of stuff. Angular tends to favor declarative manipulation of the dom rather than a imperative one(at least that's the way I've been playing with it).

的标记

<table class="table">
  <thead>
    <tr>
      <th>
        <input type="checkbox" 
          ng-click="selectAll($event)"
          ng-checked="isSelectedAll()">
      </th>
      <th>Title</th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="e in entities" ng-class="getSelectedClass(e)">
      <td>
        <input type="checkbox" name="selected"
          ng-checked="isSelected(e.id)"
          ng-click="updateSelection($event, e.id)">
      </td>
      <td>{{e.title}}</td>
    </tr>
  </tbody>
</table>

和在控制器

var updateSelected = function(action, id) {
  if (action === 'add' && $scope.selected.indexOf(id) === -1) {
    $scope.selected.push(id);
  }
  if (action === 'remove' && $scope.selected.indexOf(id) !== -1) {
    $scope.selected.splice($scope.selected.indexOf(id), 1);
  }
};

$scope.updateSelection = function($event, id) {
  var checkbox = $event.target;
  var action = (checkbox.checked ? 'add' : 'remove');
  updateSelected(action, id);
};

$scope.selectAll = function($event) {
  var checkbox = $event.target;
  var action = (checkbox.checked ? 'add' : 'remove');
  for ( var i = 0; i < $scope.entities.length; i++) {
    var entity = $scope.entities[i];
    updateSelected(action, entity.id);
  }
};

$scope.getSelectedClass = function(entity) {
  return $scope.isSelected(entity.id) ? 'selected' : '';
};

$scope.isSelected = function(id) {
  return $scope.selected.indexOf(id) >= 0;
};

//something extra I couldn't resist adding :)
$scope.isSelectedAll = function() {
  return $scope.selected.length === $scope.entities.length;
};

修改 getSelectedClass()预计整个实体,但它被调用时只使用实体,这是目前矫正的ID

EDIT: getSelectedClass() expects the entire entity but it was being called with the id of the entity only, which is now corrected

这篇关于如何应对在AngularJS指令上复选框的点击?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆