J'ai construit une directive 'accessLevel' dans l'angle 4 qui fonctionne comme * ngIf mais sur différents niveaux d'autorisations.Angular 4- Comment lier la propriété à la directive *
@Directive({
selector: '[accessLevel]'
})
export class AccessLevelDirective {
private levelToPredicateMapper: {[id: string] :() => Observable<boolean>} = {};
private isAuthorized: boolean;
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private readonly credentialsStorage: CredentialsStorageService,
private readonly authentication: AuthenticationService) {
this.createAccessLevelToPredicatesMapper();
}
@Input() set accessLevel(level: string) {
if (level == null) {
return;
}
let hasAccessLevelFunc = this.levelToPredicateMapper[level];
if (hasAccessLevelFunc == null) {
this.viewContainer.clear();
return;
}
hasAccessLevelFunc().subscribe(hasAccessLevel => {
this.buildOrDestroyView(hasAccessLevel);
})
}
@Input() set roles(roles: [string]) {
this.authentication.isAuthenticated()
.subscribe(isAuthenticated => {
let isValidRolesArray = roles != null && Array.isArray(roles) && roles.length > 0;
let isUserHasOneOfTheRoles = isAuthenticated &&
isValidRolesArray &&
this.credentialsStorage.get() &&
some(this.credentialsStorage.get().roles , role => roles.indexOf(role) > -1);
this.buildOrDestroyView(isUserHasOneOfTheRoles);
})
}
private buildOrDestroyView(isAuthorized: boolean) {
let isStateChanged = isAuthorized !== this.isAuthorized;
if (!isStateChanged) return;
this.isAuthorized = isAuthorized;
if (isAuthorized) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
private createAccessLevelToPredicatesMapper() {
this.levelToPredicateMapper['all'] =() => Observable.of(true);
this.levelToPredicateMapper['guest'] =() => this.authentication.isAuthenticated().map(isAuth => !isAuth);
this.levelToPredicateMapper['authenticated'] =() => this.authentication.isAuthenticated()
}
}
Mon problème est lorsque je l'utilise à l'intérieur du code HTML. afin de lier à la propriété de rôle, j'ai besoin d'envelopper l'élément avec ng-template.
<!--Without [roles]-->
<a class="nav-item nav-link text-uppercase" *accessLevel="'authenticated'">
...
</a>
<!--with [roles]-->
<ng-template accessLevel [roles]="['admin']">
...
</ng-template>
Est-il possible que je peux lier les rôles sans qu'il soit nécessaire d'envelopper l'élément avec ng-modèle?
Semble '* accessLevel =" rôles: ['admin'] "' ne se trompe pas. '' accessLevel = "quelque chose; roles: ['admin']" ' – yurzui
Bon, je suis déjà tombé sur quelque chose comme ça il y a un moment. –
'* accessLevel =" 0, rôles: ['admin'] "' ou '* accessLevel =" 'authentifié', rôles: ['admin'] "' – yurzui