Die Lösung ist in diesem Fiddle:
http://jsfiddle.net/BmQuY/3/
var app = angular.module('myApp', []);
app.service('authService', function(){
var user = {};
user.role = 'Gast';
return{
getUser: function(){
return user;
},
generateRoleData: function(){
/* Dies wird aufgelöst, bevor der
Router die Ansicht und das Modell lädt.
Es muss ein Promise zurückgeben. */
/* ... */
}
}
});
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 */
}
}
}
});
Wenn Sie diese Direktive mit IE 7 oder 8 verwenden möchten, müssen Sie die Kinder des Elements manuell entfernen, sonst wird ein Fehler ausgegeben:
angular.forEach(element.children(), function(elm){
try{
elm.remove();
}
catch(ignore){}
});
Beispiel für mögliche Verwendung:
Administrative Optionen
Unittest mit Karma + Jasmine: Achtung: Die done
Rückruffunktion ist nur für Jasmine 2.0 verfügbar. Wenn Sie 1.3 verwenden, sollten Sie stattdessen waitsFor verwenden.
describe('restrict-remove', function(){
var scope, compile, html, elem, authService, timeout;
html = '';
beforeEach(function(){
module('myApp.directives');
module('myApp.services');
inject(function($compile, $rootScope, $injector){
authService = $injector.get('authService');
authService.setRole('Gast');
scope = $rootScope.$new();
// compile = $compile;
timeout = $injector.get('$timeout');
elem = $compile(html)(scope);
elem.scope().$apply();
});
});
it('sollte eine einfache rollenbasierte Inhaltsdiskretion ermöglichen', function(done){
timeout(function(){
expect(elem).toBeUndefined();
done(); //möglicherweise benötigt einen längeren Timeout;
}, 0);
});
});
describe('restrict-keep', function(){
var scope, compile, html, elem, authService, timeout;
html = '';
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('soll Benutzern mit ausreichenden Berechtigungen ermöglichen, eingeschränkten Inhalte anzuzeigen', function(done){
timeout(function(){
expect(elem).toBeDefined();
expect(elem.length).toEqual(1);
done(); //möglicherweise benötigt einen längeren Timeout;
}, 0)
})
});
Eine generische Zugriffskontrolldirektive für Elemente, ohne Verwendung von ng-if (nur seit V1.2 - derzeit instabil) oder ng-show, das das Element nicht tatsächlich aus dem DOM entfernt.