显示基于用户的角色的单个视图中的不同的内容
假设我们有我的角度SPA应用程序中的菜单,现在我要显示给所有用户的基本选项,如主页,关于我们,运营商的机会等。
Let's assume that we have a menu within my angular SPA application, now I want the basic options to be displayed to all of the users, such as home, about us, carrier opportunities etc.
我也想有其他几个选项,如管理用户,疥癣等职位,将只显示给管理员。
I would also like to have several other options, such as manage users, mange posts etc, that will be displayed only to an admin.
让我们假设我们有一个API接入点为我提供了用户角色,或者更好的是,用户的角色是从检索到的对象中/ API /用户/我的。
Let's also assume that we have an API access point that provides me with the user role, or better yet, that the user role is within the object that retrieved from /api/users/me.
什么是从由普通用户正在观看?封装这些管理工具的最佳方式。
What would be the best way to encapsulate those management tools from being viewed by regular users?.
是否有某种看法之间的继承?像Django的?有没有办法隐藏从未经授权的用户的DOM元素?(是的,我知道这是客户端)。
Is there some kind of inheritance among views? like in Django?, is there any way to hide the DOM elements from the unauthorized user?(yes, I know that it's client side).
我真的preFER不使用不同意见的菜单,因为它应该是一个通用组件。
I'd really prefer not to use different views for the menu, since it's supposed to be a generic component.
我想,如果回答我所有的previous的问题是没有,剩下的问题是:什么是我们的最佳执行?一个自定义指令(E+A)
说:
I suppose that if the answer to all my previous question is no, the question that remains is: what is the best implementation for this? a custom directive("E" + "A") say:
<limitedAccss admin>Edit page</limitedAccess>
<limitedAccss user>view page</limitedAccess>
或者只是使用常规的NG-显示与用户对象上的情况?
or perhaps just using the regular ng-show with a condition on the user object?.
解决方法就是在这个提琴:
The solution is in this fiddle:
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*/
/*...*/
}
}
});
app.directive('restrict', function(authService){
return{
restrict: 'A',
priority: 100000,
scope: false,
link: function(){
// alert('ergo sum!');
},
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();
}
}
}
});
如果你想使用这个指令与IE 7或8,你需要手动删除元素的孩子,否则错误会抛出:
if you want to use this directive with IE 7 or 8, you'll need to remove the element's children manually, otherwise an error will be throw:
angular.forEach(element.children(), function(elm){
try{
elm.remove();
}
catch(ignore){}
});
可以使用示例:
<div data-restrict access='superuser admin moderator'><a href='#'>Administrative options</a></div>
使用噶+茉莉花
单元测试:
注意:的完成
的回调函数仅适用于茉莉花2.0,如果您使用的是1.3,你应该使用的 waitsFor 来代替。
Unit test using Karma + Jasmine:
Attention: the done
callback function is only available for Jasmine 2.0, if you are using 1.3, you should use waitsFor instead.
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-显示它实际上并没有从DOM删除元素
A generic access control directive for elements, without using ng-if(only since V1.2 - currently unstable), or ng-show which doesn't actually remove the element from the DOM.