AngularJS实现多选框分段全选与取消全选联动
在前端开发中,列表批量选择功能几乎是每个项目都绕不开的常见需求。无论是后台管理系统还是普通Web应用,处理批量操作时总需要与复选框打交道。虽然实现方式多种多样,但核心逻辑基本一致。本文将从AngularJS角度出发,详细拆解一个典型的分段全选场景——既支持按大类全选,又允许在每个大类内部单独勾选子项。简单来说,就是实现“全选父级→子项全部勾选,反选任意子项→父级全选自动取消”的联动效果。

HTML结构代码
首先来看模板部分的实现。整体结构非常清晰:外层使用 ng-repeat 指令遍历大类列表(todolist),每个大类内部再通过 ng-repeat 循环渲染子权限项。关键绑定只有两处——大类顶部的复选框负责全选或取消全选,子项复选框则负责单独选中或取消。
角色权限:
{{todotype.type}}
{{obj.name}}
下面对 ng-model 绑定细节做进一步说明:
- 大类复选框绑定了
$parent.selectAll[$index],其中$parent用于跳出当前ng-repeat作用域,从而直接访问控制器中的$scope.selectAll数组。每个大类对应数组中的一个布尔值,用于控制该组的全选状态。 - 子项复选框绑定了
obj.isSelected,该属性在数据初始化时动态添加,用于标识每个子项的选中状态。 - 点击事件分为两种:
changeAll($index)负责大类全选或取消全选时同步所有子项的选中状态;funcChange($parent.$index)则用于子项状态改变时判断当前大类是否应取消全选。
AngularJS控制器代码实现
首先来看数据初始化部分。从后端接口获取数据后,需要为每个权限项添加 isSelected: false 属性。同时维护一个 selectAll 数组,其长度与大类的数量保持一致,初始值全部设为 false。
// 获取数据 这里具体post请求就不写了
$scope.todolist = res.data.data;
for(var i = 0; i < $scope.todolist.length; i++) {angular.forEach($scope.todolist[i].permissionList, function(i) { i.isSelected = false;})
}
// 数据类型如下
$scope.list = [{
permissionList: [{
name: 'Golde',
// birthday: '2000-01-10',
isSelected: false
},
{
name: 'King',
// birthday: '1990-01-10',
isSelected: false
},
{
name: 'Mark',
// birthday: '19890-01-10',
isSelected: false
},
{
name: 'Marie',
// birthday: '2010-01-10',
isSelected: false
}
],
type: "制造资源管理"
}, {
permissionList: [{
name: 'Golde1',
// birthday: '2000-01-10',
isSelected: false
},
{
name: 'King1',
// birthday: '1990-01-10',
isSelected: false
},
{
name: 'Mark1',
// birthday: '19890-01-10',
isSelected: false
},
{
name: 'Marie1',
// birthday: '2010-01-10',
isSelected: false
}
],
type: "制造资源管理2"
}, {
permissionList: [{
name: 'Golde2',
// birthday: '2000-01-10',
isSelected: false
},
{
name: 'King2',
// birthday: '1990-01-10',
isSelected: false
},
{
name: 'Mark2',
// birthday: '19890-01-10',
isSelected: false
},
{
name: 'Marie2',
// birthday: '2010-01-10',
isSelected: false
}
],
type: "制造资源管理3"
}];
以下是两个核心方法的具体实现:
// 这里初始化数组 上来全为空
$scope.selectAll = [];
// 对于对象进行操作的时候(点击),会执行funcChange
// 判断对象数组中isSelected 是否为 true或false,在决定select是否为true
$scope.changeAll = function(index) { //全选/取消全选
angular.forEach($scope.todolist[index].permissionList, function(v, k) {
v.isSelected = $scope.selectAll[index];
})
};
$scope.funcChange = function(index) { // 当所有都选中时
$scope.selectAll[index] = true;
angular.forEach($scope.todolist[index].permissionList, function(v, k) {
$scope.selectAll[index] = $scope.selectAll[index] && v.isSelected;
});
};
changeAll 的逻辑非常直观:点击大类复选框时,$scope.selectAll[index] 已通过 ng-model 的双向绑定自动更新为当前复选框的值,随后将该值賦予该大类下所有子项的 isSelected。如此,大类选中则子项全部勾选,大类取消则子项全部清空。
funcChange 相对复杂一些:每次点击子项时都会触发该函数。它先将 $scope.selectAll[index] 设置为 true,然后遍历当前大类所有子项的 isSelected 属性,通过 && 运算符进行累加判断——只要有一个子项未选中,最终结果即为 false,从而将大类复选框置为未全选状态。若所有子项均被选中,大类复选框则会自动点亮。
整个逻辑并不复杂,关键在于充分利用 ng-model 的双向绑定机制以及事件触发的时机。只要掌握了“点击大类时同步子项”和“点击子项时反向判断大类”这两个核心流程,实现分段全选功能就变得轻而易举了。
