2017-10-10 105 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

相關問題