管理AngularJS中的多对多关系

时间:2013-05-10 15:01:11

标签: ruby-on-rails angularjs

我有两个具有多对多关联的模型 - 角色具有许多权限,同样权限可能属于多个角色。

现在我有一个允许用户创建新角色的视图;我想为他们添加一个功能,让他们可以选择角色拥有的权限,以及创建/删除权限并分配权限。这就是我现在正在看的内容:

示例角色JSON

现在我在每个角色中嵌套当前分配的权限:

{
  id: 1,
  name: "Manager",
  permissions: [
    {
      id: 2,
      name: "Send Email"
    }
  ]
}

RoleCtrl:

MyApp.factory('Role', function($resource) {
  var Role = $resource('roles/:id', {id: '@id'}, {});
  return Role;
}).factory('Permission', function($resource) {
  var Permission = $resource('permissions/:id', {id: '@id'}, {});
  return Permission;
});

function RoleCtrl($scope, $routeParams, Role, Permission) {
  $scope.role = Role.get({id: $routeParams.id });
  $scope.permissions = Permission.query();

  $scope.role.save = function() {  
    $scope.role.$update(
      function() { /* success */ }, 
      function(response) { /* errors */ }
    );
  };

  $scope.hasPermission = function(permission) {
    return _.find($scope.role.permissions, function(p) {
      return p.id == permission.id;
    }) !== undefined;
  };
}

视图

<div ng-controller="RoleCtrl">
  <form ng-submit="save()">
    <input type="text" ng-model="role.name">
    <button type="submit">Submit</button>
    <ul>
      <li ng-repeat="permission in permissions">
        <label class="checkbox">
          <input type="checkbox" value="{{permission.name}}" ng-checked="hasPermission(permission)">{{permission.name}}
        </label>
      </li>
      </ul>
  </form>
</div>

到目前为止,我所完成的只是正确设置了复选框的初始值,但我有一种感觉,我可能会以错误的方式进行此操作。我对Angular很新,所以我想弄清楚最好的方法是什么:

  1. 如果复选框更改
  2. ,则更新与角色关联的权限
  3. 在编辑角色时创建新权限或删除权限。

2 个答案:

答案 0 :(得分:1)

对于第一部分(现在没有足够的时间考虑第二部分,稍后会回来):

我会写一个函数来更新控制器中的权限,使用ng-click绑定。 该函数接受权限和正在编辑的角色,并添加/删除正在编辑的权限。

function RoleCtrl($scope, $routeParams, Role, Permission) {
    $scope.togglePermission = function(role,permission){
        if($scope.hasPermission(permission){
            // get the index of this permission role
            $scope.role.permissions.splice(index,1);
        }else{
            $scope.role.permissions.push(permission)
        }
    }
}

您的观点可能看起来像这样

  <li ng-repeat="permission in permissions">
    <label class="checkbox" ng-click="togglePermission(role,permission)">
      <input type="checkbox" value="{{permission.name}}" ng-checked="hasPermission(permission)">{{permission.name}}
    </label>
  </li>

答案 1 :(得分:0)

我构建了一个jsfiddle来演示可能适合您的角度客户端数据结构: https://jsfiddle.net/gavinpalmer1984/cboh22dg/

angular
    .module('rolling', [])
    .directive('rolesDemo', function() {
        return {
            controllerAs: 'demo',
            controller: function() {
                var vm = this;
                vm.roles = {};
                vm.permissions = {};
                vm.createRole = function() {
                    var id = Object.keys(vm.roles).length;
                    var tmp = {};
                    tmp.name = id;
                    tmp.id = id;
                    tmp.permissions = [];
                    vm.roles[id] = tmp;
                    //console.log('create role', vm.roles);
                };
                vm.createPermission = function() {
                    var id = Object.keys(vm.permissions).length;
                    var tmp = {};
                    tmp.name = id;
                    tmp.id = id;
                    tmp.roles = [];
                    vm.permissions[id] = tmp;
                    //console.log('create permission', vm.permissions);
                };
                vm.selectRole = function(id) {
                    vm.selected_role = id;
                }
                vm.selectPermission = function(id) {
                    vm.selected_permission = id;
                }
                vm.changePermission = function(id) {
                    vm.roles[vm.selected_role].permissions = [];
                    angular.forEach(vm.checked[vm.selected_role], function(val, key) {
                        var index = vm.permissions[id].roles.indexOf(vm.selected_role);
                        if (val) {
                            vm.roles[vm.selected_role].permissions.push(key);
                            if (index === -1) {
                                vm.permissions[id].roles.push(vm.selected_role);
                            }
                        } else if (key === id && !val) {
                            if (index !== -1) {
                                vm.permissions[id].roles.splice(index, 1);
                            }
                        }
                    });
                    console.log(vm.permissions[id]);
                };
            },
            template: "".toString() +
                '<button ng-click="demo.createRole()">create role</button><button ng-click="demo.createPermission()">create permission</button>' +
                '<div>' +
                '   roles: <button ng-repeat="role in demo.roles" ng-click="demo.selectRole(role.id)">{{role.name}}</button>' +
                '</div>' +
                '<div>' +
                '   permissions: <button ng-repeat="perm in demo.permissions" ng-click="demo.selectPermission(perm.id)">{{perm.name}}</button>' +
                '</div>' +
                '<div ng-show="demo.selected_role === 0 || demo.selected_role">' +
                '   selected role: {{demo.selected_role}}<br>' +
                '   <div ng-repeat="perm in demo.permissions">' +
                '   <input type="checkbox" value="{{perm.id}}" ng-change="demo.changePermission(perm.id, true)" ng-model="demo.checked[demo.selected_role][perm.id]"/>{{perm.name}}' +
                '   </div>' +
                '</div>' +
                '<div ng-show="demo.selected_permission === 0 || demo.selected_permission">' +
                '   selected permission: {{demo.selected_permission}}<br>' +
                '   <div ng-repeat="role_id in demo.permissions[demo.selected_permission].roles">' +
                '       role {{role_id}}' +
                '   </div>' +
                '</div>'
        };
    });
相关问题