AngularJS 1.2中ng-model用表达式实现复选框双向绑定问题
解决AngularJS中复选框ng-model双向绑定问题
首先,咱们得先搞清楚你原来的写法为什么不行:ng-model需要绑定到一个可被赋值的变量/属性,而你之前绑定的p.grants.indexOf('Delete') != -1?true:false是一个一次性的表达式——它只能计算出当前状态,但当用户点击复选框时,AngularJS没法给这个表达式赋值,自然就失去了双向绑定的能力。
下面给你两种可行的解决方案,根据你的实际场景选择:
方案1:针对单个权限(比如你的Delete示例)
步骤1:在控制器中维护选中状态属性
先给userRoles添加一个selected对象,用来存储每个权限的选中状态,同时初始化它的初始值(根据grants数组):
$scope.userRoles = { grants: ["Permission", "View", "Update", "Delete"], selected: {} // 用来存每个权限的选中状态 }; // 初始化选中状态:根据grants数组设置对应的selected属性 angular.forEach($scope.userRoles.grants, function(grant) { $scope.userRoles.selected[grant] = true; });
步骤2:修改HTML绑定到状态属性
把ng-model绑定到userRoles.selected.Delete,这样就能实现双向绑定了:
<div> <input type="checkbox" ng-model="userRoles.selected.Delete" ng-change="AddRemovePermission(userRoles, 'Delete')" /> <span>Delete</span> </div>
步骤3:更新AddRemovePermission函数
让它根据选中状态来同步grants数组:
$scope.AddRemovePermission = function(role, permission) { var grantIndex = role.grants.indexOf(permission); if (role.selected[permission]) { // 如果选中且数组里没有,就添加 if (grantIndex === -1) { role.grants.push(permission); } } else { // 如果未选中且数组里有,就移除 if (grantIndex !== -1) { role.grants.splice(grantIndex, 1); } } };
方案2:遍历所有权限(更通用的场景)
如果你需要展示多个权限复选框,而不是只针对Delete,可以用这种更通用的方式:
步骤1:定义所有可选权限并初始化状态
// 先列出所有可能的权限 $scope.allPermissions = ["Permission", "View", "Update", "Delete"]; $scope.userRoles = { grants: ["Permission", "View", "Update", "Delete"] }; // 创建中间对象存储选中状态 $scope.selectedPermissions = {}; // 初始化选中状态 angular.forEach($scope.allPermissions, function(perm) { $scope.selectedPermissions[perm] = $scope.userRoles.grants.indexOf(perm) !== -1; }); // 监听选中状态变化,同步到grants数组 $scope.$watch('selectedPermissions', function(newSelection) { $scope.userRoles.grants = []; angular.forEach(newSelection, function(isSelected, perm) { if (isSelected) { $scope.userRoles.grants.push(perm); } }); }, true); // 这里的true是深度监听对象内部属性变化
步骤2:HTML循环渲染所有权限复选框
<div ng-repeat="perm in allPermissions"> <input type="checkbox" ng-model="selectedPermissions[perm]" id="perm-{{perm}}" /> <label for="perm-{{perm}}">{{perm}}</label> </div>
这样不管是用户点击复选框,还是userRoles.grants数组在其他地方被修改,选中状态都会自动同步,完美实现双向绑定。
内容的提问来源于stack exchange,提问作者vishalsingh
相关产品推荐
相关产品推荐

