javascript - Angular 1 : check all check boxes in a large ng-repeat

标签 javascript html angularjs checkbox

我有一个使用 ng-repeat 创建的表,其中有数百行,最多 600 或 700 行。每一行都包含一个复选框,顶部有一个“全部选中”框,可以一次性选中所有框。然而,我遇到了浏览器性能问题,IE11(客户的首选)尤其变得没有响应。几分钟后,所有复选框都显示为选中状态,但您仍然无法滚动或执行任何操作,因此它实际上毫无用处。

我创建了一个 Controller 数组,当单击 checkAll 框时,它会循环遍历模型(ng-repeat 中使用的模型)并向数组添加一个值。我认为是数组的循环导致了速度减慢,但我不确定。分页已被排除,他们希望所有行都在一页上。

<table>
  <tbody>
    <tr>
      <th>Table Header</th>
      <th><input type="checkbox" id="checkAllCheckBox" ng-model="vm.allChecked" ng-change="vm.tickOrUntickAllCheckBoxes()" /> 
    </tr>
    <tr ng-repeat="payment in vm.payments>
      <td>{{ payment.somePaymentValue }}</td>
      <td>
          <input type="checkbox" class="paymentsApprovalCheckbox" 
              ng-checked="vm.approvedPayments.indexOf(payment.payId) > - 1"
              ng-value="payment.payId" ng-model="payment.approved" 
              ng-click="vm.handleCheckBoxClick(payment.payId)" /> 
      </td>
    </tr>
  </tbody>
</table>

这是检查/取消选中所有的 Angular 函数

vm.tickOrUntickAllCheckBoxes = function(){
    if (vm.allChecked == false) {
        vm.approvedPayments = [];
    } else {    
        vm.payments.forEach(function(payment){
            vm.approvedPayments.push(payment.payId);
        });
    }
};

将 Angular vm.tickOrUntickAllCheckBoxes() 函数替换为普通的旧 JavaScript 选项,使得 checkAll 框几乎可以在 IE11 中立即工作,但是我无法访问已检查的 payment.payId 值。我想知道 Angular 有没有办法得到它们?这是简单的 javascript checkAll() 函数:

<script>
    function checkAll(x) {
        var checkBoxes = document.getElementsByClassName('paymentsApprovalCheckbox');
        for (var i = 0; i < checkBoxes.length ; i++) {
            checkBoxes[i].checked = (x.checked == true);
        }
    }
</script>  

然后我像这样更新 checkAll 复选框:

<input type="checkbox" id="checkAllCheckBox" ng-model="vm.allChecked" onclick="checkAll(this)" />

如果您单独选中一个复选框,则重复复选框中的 ng-model="payment.approved"会更新,但如果使用 checkAll 函数选中它们,则不会发生这种情况。 Angular 是否可以检测使用 checkAll() 检查的框?我想这只是将同样不可避免的放缓推迟到稍晚一点的过程。

有人有任何想法或解决方法吗?谢谢!

最佳答案

我会充分利用 ng-model 的能力。在你的 Controller 中:

$onInit() {
  // If you need this from a REST call to populate, you'll have to
  // remember to do that here;
  this.model = {
    all: true,
    items: {}
  };
}

在你的循环中:

<tr>
  <th>Table Header</th>
  <th>
    <input type="checkbox"
      id="checkAllCheckBox"
      ng-model="vm.model.all"
      ng-change="vm.tickOrUntickAllCheckBoxes()" /> 
</tr>
<tr ng-repeat="payment in vm.payments track by $index">
  <td ng-bind="payment.somePaymentValue"></td>
  <td>
      <input type="checkbox"
        class="paymentsApprovalCheckbox" 
        ng-change="vm.approvedPayments($index)"
        ng-model="vm.model.items[$index]" /> 
  </td>
</tr>

然后在你的 Controller 中:

tickOrUntickAllCheckBoxes() {
  const boxes = this.model.items.length;
  this.model.all = !this.model.all;
  // Several ways to do this, forEach, map, etc.,
  this.model.items.forEach((item) => { item.checked = !this.model.all });
}

单独设置:

approvedPayments(idx) {
  // Sets all the item's boxes checked, or unchecked;
  this.model.items[idx].checked = !this.model.items[idx].checked;

  // Possible call to extended model to get payment info; 
  handleCheckBoxClick(idx);
}

您应该能够将所有付款信息放入一个approvedPayments()方法中,而不是使用两个单独的方法(将逻辑从模板移出并移入 Controller 或服务中)。也就是说,您的模型可能如下所示:

this.model.items = [
  // One 'option' with id, payment etc;
  {
    id: 73,
    paymentId: 73,
    somePaymentValue: 210.73,
    currencyType: 'GBP',
    checked: false
  },
  {
    // Another 'option' etc...
  }
]

需要注意的一个问题是 ngChecked with ngModel 不兼容,必须查找它(这就是为什么我在上面没有使用 ng-checked 的原因)。

关于javascript - Angular 1 : check all check boxes in a large ng-repeat,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46914458/

相关文章:

javascript - 如何让 ReactJS 呈现空的 HTML 属性

javascript - Firebase 身份验证模拟器因 IDP 失败

javascript - 单选下拉菜单

javascript - ng-bind-html 获取html内容的首字母

javascript - 如何在 Angularjs 中打印表单内的数组值?

javascript - 我放入文件夹中的 .png 文件没有出现在我的包中

javascript - 将全局变量传递给另一个 View 主干

html - 如何将不同大小的图像放置在 2 列中并对齐 figcaption

html - 无法在各自的文件夹中访问网站 css 和 javascript

javascript - Angular ngGrid 在页面加载时选择行