我有一个使用ng-repeat创建的表,有数百行,最多600或700.每行包含一个复选框,我有一个"全部检查"顶部的方框可以一次性检查所有方框。但是,我遇到了浏览器性能问题,IE11(客户首选)尤其没有响应。几分钟后,所有复选框都显示为已选中,但您仍然无法滚动或执行任何操作,因此无效。
我创建了一个控制器数组,当单击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>
这是检查/取消选中所有
的角度函数vm.tickOrUntickAllCheckBoxes = function(){
if (vm.allChecked == false) {
vm.approvedPayments = [];
} else {
vm.payments.forEach(function(payment){
vm.approvedPayments.push(payment.payId);
});
}
};
更换一个普通的旧javascript选项的angular vm.tickOrUntickAllCheckBoxes()函数使得checkAll框几乎在IE11中即时工作,但是我无法访问已检查的payment.payId值。我想知道是否有角度来获取它们?这是普通的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 =&#34; payment.approved&#34;在重复复选框中更新,但如果使用checkAll函数检查它们,则不会发生这种情况。角度是否可以检测用checkAll()检查的方框?我想这只是推迟了相同的旧的不可避免的减速到稍后的一点。
任何人都有任何想法或解决方法吗?谢谢!
答案 0 :(得分:1)
我会尽力使用ng-model。在您的控制器中:
$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>
然后在你的控制器中:
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()方法,而不是使用两个单独的方法(将逻辑移出模板并进入控制器或服务)。即,您的模型可能如下所示:
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)。
答案 1 :(得分:0)
感谢大家的建议。我想出的解决方案是将一些工作推回到服务器端。我只是在页面加载时加载两个额外的模型,而不仅仅是加载付款模型(其中每个付款记录包含大量信息),其中一个是一组键/值对,其中键是payId和值都是假的,另一个具有相同的键,所有值都是真的。例如:
{
"1": false,
"2": false
}
这些用于checkAll / Uncheck all - 只需将vm.approvedIDs变量设置为true或false。然后,vm.approvedIDs变量用作ng-repeat复选框中的模型。
当用户将approvedID发送回服务器时,我必须在服务器端做一些额外的工作才能获得&#39; true&#39;的密钥/ ID。条目。以下是相关的角度控制器功能:
$onInit() {
// call http to get 'data' from server
vm.payments = data.payments;
vm.paymentIDsFalse = vm.approvedIDs = data.paymentIDsFalse;
vm.paymentIDsTrue = data.paymentIDsTrue;
};
// tick/untick all boxes
vm.tickOrUntickAllCheckBoxes = function(){
if (vm.allChecked == false) {
vm.approvedPayments = vm.paymentIDsFalse;
} else {
vm.approvedPayments = vm.paymentIDsTrue;
}
};
// tick/untick one box
vm.handleCheckBoxClick = function(payId, currentValue){
vm.approvedPayments[payId] = currentValue;
};
vm.submitApprovedIds = function(){
// post vm.approvedPayments to server
};
HTML:
<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-value="payment.payId"
ng-model="vm.approvedPayments[payment.payId]"
ng-click="vm.handleCheckBoxClick(payment.payId, vm.approvedPayments[payment.payId])" />
</td>
</tr>
</tbody>
</table>
在我看来,似乎必须有一个比创建这些额外模型更好的方法,但它现在工作得相当顺利,我可以继续下一步!