根据用户的角色在单个视图中显示不同的内容

发布于 2021-02-01 10:02:08

假设我的角度SPA应用程序中有一个菜单,现在我希望向所有用户显示基本选项,例如家庭,关于我们,承运商的机会等。

我还希望有其他一些选项,例如管理用户,管理职位等,这些选项只会显示给管理员。

我们还假设我们有一个API访问点,可以为我提供用户角色,或者更好的是,该用户角色位于从/ api / users / me检索的对象内。

封装那些管理工具以防止普通用户查看的最佳方法是什么?

视图之间是否有某种继承?就像在Django中一样,有没有办法向未经授权的用户隐藏DOM元素?(是的,我知道这是客户端)。

我真的不希望菜单使用不同的视图,因为它应该是通用组件。

我想如果我之前所有问题的答案都是“否”,那么剩下的问题就是:什么是最佳的实现方案?一个自定义指令(“ E” +“ A”)说:

<limitedAccss admin>Edit page</limitedAccess>
 <limitedAccss user>view page</limitedAccess>

还是仅在用户对象上使用条件的常规ng-show?

关注者
0
被浏览
68
1 个回答
  • 面试哥
    面试哥 2021-02-01
    为面试而生,有面试问题,就找面试哥。

    解决方法是在这个小提琴中:

    http://jsfiddle.net/BmQuY/3/

    var app = angular.module('myApp', []);
    
    app.service('authService', function(){
    
      var user = {};
      user.role = 'guest';
      return{
        getUser: function(){
          return user;
        },
        generateRoleData: function(){
          /* this is resolved before the 
             router loads the view and model.
             It needs to return a promise. */
          /* ... */
        }
      }
    });
    
    app.directive('restrict', function(authService){
        return{
            restrict: 'A',
            priority: 100000,
            scope: false,
            compile:  function(element, attr, linker){
                var accessDenied = true;
                var user = authService.getUser();
    
                var attributes = attr.access.split(" ");
                for(var i in attributes){
                    if(user.role == attributes[i]){
                        accessDenied = false;
                    }
                }
    
    
                if(accessDenied){
                    element.children().remove();
                    element.remove();           
                }
    
    
                return function linkFn() {
                    /* Optional */
                }
            }
        }
    });
    

    如果要在IE 7或8中使用此指令,则需要手动删除元素的子级,否则将引发错误:

      angular.forEach(element.children(), function(elm){
        try{
          elm.remove();
        }
        catch(ignore){}
      });
    

    可能的用法示例:

    <div data-restrict access='superuser admin moderator'><a href='#'>Administrative options</a></div>
    

    使用噶+茉莉花单元测试: 注意:
    done回调函数仅适用于茉莉花2.0,如果您使用的1.3,你应该使用waitsFor代替。

      describe('restrict-remove', function(){
        var scope, compile, html, elem, authService, timeout;
        html = '<span data-restrict data-access="admin recruiter scouter"></span>';
        beforeEach(function(){
          module('myApp.directives');
          module('myApp.services');
          inject(function($compile, $rootScope, $injector){
            authService = $injector.get('authService');
            authService.setRole('guest');
            scope = $rootScope.$new();
            // compile = $compile;
            timeout = $injector.get('$timeout');
            elem = $compile(html)(scope);
            elem.scope().$apply();
          });
        });
        it('should allow basic role-based content discretion', function(done){
            timeout(function(){
              expect(elem).toBeUndefined(); 
              done(); //might need a longer timeout;
            }, 0);
        });
      });
      describe('restrict-keep', function(){
        var scope, compile, html, elem, authService, timeout;
        html = '<span data-restrict data-access="admin recruiter">';
        beforeEach(function(){
          module('myApp.directives');
          module('myApp.services');
          inject(function($compile, $rootScope, $injector){
            authService = $injector.get('authService');
            timeout = $injector.get('$timeout');
            authService.setRole('admin');
            scope = $rootScope.$new();
            elem = $compile(html)(scope);
            elem.scope().$apply();
          });
        });
    
        it('should allow users with sufficient priviledsges to view role-restricted content', function(done){
          timeout(function(){
            expect(elem).toBeDefined();
            expect(elem.length).toEqual(1);
            done(); //might need a longer timeout;
          }, 0)
        })
      });
    

    元素的通用访问控制指令,不使用ng-if(仅自V1.2-当前是不稳定的)或ng-show,它们实际上并未从DOM中删除元素。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看