我们假设我有一个菜单在我的角度的SPA应用程序,现在我想要显示给所有的用户,如家庭,关于我们,操作符机会等基本选项。
我也想有几个其他选项,如管理用户,管理帖子等,只显示给管理员。
我们还假设我们有一个API访问点,它为我提供用户角色,或者更好的是,用户角色在从/ api / users / me中检索的对象内。
观点之间有什么继承吗?像Django吗?有没有办法从未经授权的用户隐藏DOM元素?(是的,我知道这是客户端)。
我真的不希望在菜单中使用不同的视图,因为它应该是一个通用组件。
我想如果以前所有问题的答案都不是,那么剩下的问题是:最好的实现是什么?自定义指令(“E”“A”)
说:
<limitedAccss admin>Edit page</limitedAccess> <limitedAccss user>view page</limitedAccess>
或者只是使用正常的ng-show和用户对象的条件?
解决方案是在这个小提琴:
原文链接:https://www.f2er.com/angularjs/145118.htmlvar 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>
使用Karma Jasmine进行单元测试:
注意:完成的回调函数仅适用于Jasmine 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',timeout; html = '<span data-restrict data-access="admin recruiter">'; beforeEach(function(){ module('myApp.directives'); module('myApp.services'); inject(function($compile,$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移除元素)。