具有服务调用的Angular 2结构指令

时间:2017-09-27 18:15:07

标签: angular angular-directive

我创建了一个结构指令来检查用户是否具有某些权限。权限是从后端获取并保存在服务本身中。结构指令按DI注入服务,并应检查服务中是否存在权限。

这个想法:服务应该从后端获取所有权限 - >通过指令检查权限 - >渲染如果真的

问题是该服务无法获取服务。服务等待所有来自结构指令的查询,然后开始获取服务。

它看起来像这样:

authority.directive.ts

@Directive({
selector: '[authority]'}) 

export class AuthorityDirective {
constructor(private userService: UserService,
            private templateRef: TemplateRef<any>,
            private viewContainer: ViewContainerRef) {
}

@Input() set bdAuthority(authName: string) {
    if (this.userService.hasAuthority(authName)) {
        this.viewContainer.createEmbeddedView(this.templateRef);
        return;
    }
    this.viewContainer.clear();
    return;

   }
}

authority.service.ts 一样

// check if the current user has the defined privilege
public hasAuthority(authorityName: string): boolean {
    return (
        this.authorityCache
            .filter((authority) => {
                return authorityName === authority.name
            })
            .length) > 0;
}

public onBrowserReload(tempUser: User) {
     this.getUserById(tempUser.id).subscribe(user => {
                this.updatePrivilegesAndUser(user);
            });
        }
    }
}

有没有提前开始服务?

2 个答案:

答案 0 :(得分:0)

结构指令旨在根据应该预先评估的条件来更改DOM。因为在呈现视图时调用服务,此时您的服务没有返回任何内容。 根据您的要求,您应该在ngOnInit()生命挂钩中调用您的服务并将结果保存在局部变量中。 并根据您的本地变量检查条件。

答案 1 :(得分:0)

基于上次答复,我给了自己调查任务,并提出了类似问题的解决方案。

我必须从后端端点刷新一个权限数组,并在结构化指令中确定此数组,以便确定用户是否可以看到该元素,我正在使用相同的代码来解决该问题,并且出现相同的错误,对后端的权限数组调用刷新速度不够快,因此解决方案是使用和AsyncSubject。调用完成后,AsyncSubject将解析为一个值,因此您可以从方法中将其返回。

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, AsyncSubject } from 'rxjs';
import { Observable, of } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class PermissionsService {

  baseUrl = '/apiURL/v5';
  permissionsSubject = new AsyncSubject;
  hasPermissions = false;
  constructor(private http: HttpClient) { }

  async updatePermissions(clientId, roleName) {
    const response = await this.http.get(this.getRoleUrl(clientId, roleName)).toPromise();
    this.permissionsSubject.next(response['permissions'] || []);
    this.permissionsSubject.complete(); // Once I finish sending the value that I need i end the subject to propagate its value to all the subscribers.
  }

  getRoleUrl(clientId, roleName) {
    return `${this.baseUrl}/client/${clientId}/roles/${roleName}`;
  }

  setCachedPermissions(permissions) {
    this.permissionsSubject.next(permissions);
  }

  getCachedPermissions() {
    return this.permissionsSubject.asObservable();
  }
   // This is the method used by the structural directive to determine if the object is rendered
  cacheHasPermission(slug) {
    return new Promise((resolve, reject) => {
      this.getCachedPermissions().subscribe((permissions: String[]) => {
        resolve(permissions.includes(slug));
      });
    });
  }
}