Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何响应AngularJS指令中复选框的点击?_Javascript_Angularjs - Fatal编程技术网

Javascript 如何响应AngularJS指令中复选框的点击?

Javascript 如何响应AngularJS指令中复选框的点击?,javascript,angularjs,Javascript,Angularjs,我有一个AngularJS,它在以下模板中呈现一组实体: <table class="table"> <thead> <tr> <th><input type="checkbox" ng-click="selectAll()"></th> <th>Title</th> </tr> </thead> <tbody>

我有一个AngularJS,它在以下模板中呈现一组实体:

<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>
更具体地说,我想知道:

  • 上面的代码是属于控制器还是应该进入
    链接
    功能
  • 假设jQuery不一定存在(AngularJS不需要),那么进行DOM遍历的最佳方法是什么?没有jQuery,我很难只选择给定复选框的父项,或者选择模板中的所有复选框
  • $event
    传递到
    updateSelection()
    似乎不是很优雅。有没有更好的方法来检索刚刚单击的元素的状态(选中/未选中)

谢谢。

我就是这样做的。Angular倾向于对dom进行声明式操作,而不是命令式操作(至少这是我一直使用的方式)

加价

<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>

标题
{{e.title}}
在控制器中

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;
};
var updateSelected=函数(操作,id){
if(action=='add'&&$scope.selected.indexOf(id)==-1){
$scope.selected.push(id);
}
如果(操作=='remove'&&$scope.selected.indexOf(id)!=-1){
$scope.selected.splice($scope.selected.indexOf(id),1);
}
};
$scope.updateSelection=函数($event,id){
var复选框=$event.target;
var action=(checkbox.checked?'add':'remove');
updateSelected(操作,id);
};
$scope.selectAll=函数($event){
var复选框=$event.target;
var action=(checkbox.checked?'add':'remove');
对于(变量i=0;i<$scope.entities.length;i++){
var entity=$scope.entities[i];
updateSelected(action,entity.id);
}
};
$scope.getSelectedClass=函数(实体){
返回$scope.isSelected(entity.id)?“selected”:“”;
};
$scope.isSelected=函数(id){
返回$scope.selected.indexOf(id)>=0;
};
//我忍不住补充了一些额外的东西:)
$scope.isSelectedAll=函数(){
返回$scope.selected.length==$scope.entities.length;
};

EDIT
getSelectedClass()
需要整个实体,但调用它时仅使用实体的id,现在已更正该id

Liviu的回答对我非常有帮助。希望这不是一个坏的形式,但我做了一个可以帮助别人在未来

需要的两个重要部分是:

    $scope.entities = [{
    "title": "foo",
    "id": 1
}, {
    "title": "bar",
    "id": 2
}, {
    "title": "baz",
    "id": 3
}];
$scope.selected = [];
我更喜欢在需要时使用和指令。ngModel允许您将复选框的选中/未选中状态绑定到实体上的属性:

<input type="checkbox" ng-model="entity.isChecked">
。。。在控制器中

var model = {};
$scope.model = model;

// This property is bound to the checkbox in the table header
model.allItemsSelected = false;

// Fired when an entity in the table is checked
$scope.selectEntity = function () {
    // If any entity is not checked, then uncheck the "allItemsSelected" checkbox
    for (var i = 0; i < model.entities.length; i++) {
        if (!model.entities[i].isChecked) {
            model.allItemsSelected = false;
            return;
        }
    }

    // ... otherwise ensure that the "allItemsSelected" checkbox is checked
    model.allItemsSelected = true;
};
var模型={};
$scope.model=模型;
//此属性绑定到表标题中的复选框
model.allItemsSelected=false;
//选中表中的实体时激发
$scope.selectEntity=函数(){
//如果未选中任何实体,则取消选中“allItemsSelected”复选框
对于(var i=0;i
同样,标题中的“全选”复选框:

<th>
    <input type="checkbox" ng-model="model.allItemsSelected" ng-change="selectAll()">
</th>

。。。而且

// Fired when the checkbox in the table header is checked
$scope.selectAll = function () {
    // Loop through all the entities and set their isChecked property
    for (var i = 0; i < model.entities.length; i++) {
        model.entities[i].isChecked = model.allItemsSelected;
    }
};
//选中表头中的复选框时激发
$scope.selectAll=函数(){
//循环遍历所有实体并设置其isChecked属性
对于(var i=0;i
CSS

什么是最好的方法。。。将CSS类添加到包含实体的
以反映其选定状态

如果使用ngModel方法进行数据绑定,则只需将指令添加到
元素,以便在实体属性更改时动态添加或删除类:

<tr ng-repeat="entity in model.entities" ng-class="{selected: entity.isChecked}">


查看全文。

谢谢你,利维!这很管用,而且很有帮助。感谢您,我已经了解了
ngChecked
指令。(我唯一的遗憾是,我们不能让这段代码少一点冗长。)不要认为它太冗长,应该从关注点分离的角度来考虑。您的数据模型不应该知道它的呈现方式。请记住,控制器中没有提及tr或td。它最多包含复选框,但也可以排除该复选框。您可以始终将控制器应用于第二个模板;)谢谢你的提问和回答。我很想知道这种方法对效率的影响,所以我做了一个简单的解释:我注意到每次我选择一个项目,isSelected被调用6次(每个重复项目调用两次)。知道为什么每个人都会发生两次吗?有人关心在页面上放置100多个重复条目并在手机上运行吗?可能没有问题…@Aaronius如果在isSelected函数中添加断点并刷新,您将看到它在解析和执行指令内容之前被调用。我认为,因为它是一个执行替换的指令,所以所有绑定函数都被称为twice,有没有一种方法可以只知道选中的复选框?Angular docs对check all部分有一个更简单的答案。收集选中的内容是我试图弄清楚的。allItemsSelected标志在开始时设置为false,然后单击“全选”复选框时如何设置为true。你能解释一下吗?
// Fired when the checkbox in the table header is checked
$scope.selectAll = function () {
    // Loop through all the entities and set their isChecked property
    for (var i = 0; i < model.entities.length; i++) {
        model.entities[i].isChecked = model.allItemsSelected;
    }
};
<tr ng-repeat="entity in model.entities" ng-class="{selected: entity.isChecked}">