2017-10-10 111 views
2

我已经在angular 4中构建了一个'accessLevel'指令,其工作方式与* ngIf相似,但是在不同的权限级别上。Angular-4如何将属性绑定到*指令

@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() 
    } 
} 

我的问题是当我在html中使用它。为了绑定到角色属性,我需要用ng-template包装元素。

<!--Without [roles]--> 
<a class="nav-item nav-link text-uppercase" *accessLevel="'authenticated'"> 
    ...   
</a> 
<!--with [roles]--> 
<ng-template accessLevel [roles]="['admin']"> 
    ... 
</ng-template> 

有没有一种方法可以绑定角色,而无需用ng-template包装元素?

回答

1

当输入名字是相同的选择器

<input *accessLevel="['admin']" ... 

应该工作

否则输入需要是

@Input() set accessLevelRoles(roles: [string]) { 

然后

<input *accessLevel="roles:['admin']" ... 

应工作。

+1

似乎'* accessLevel =“角色:['admin']”'不会出错。 '* accessLevel =“something; roles:['admin']”' – yurzui

+0

好的,前一阵子我已经遇到过类似的情况。 –

+0

'* accessLevel =“0,roles:['admin']”'或'* accessLevel =''authenticated',roles:['admin']“' – yurzui

相关问题