0

在我的 Angular 应用程序中,我提供了请求休息 API 的服务。在进行任何调用之前,我需要从后端获取唯一的 guid 并将其作为参数传递给每个调用。所以我想我可以在构造函数中发出请求并将结果分配给这样的属性:

export class BaseApiService<T> implements OnDestroy {

  private subscription: Subscription;
  protected tenantGuid: string;

  constructor(private http: HttpClient) {
     this.subscription = this.getGuid().subscribe(data => {
        this.tenantGuid = data;
     });
  }

  private getGuid(): Observable<string> {
    return this.http.get<string>(`${this.baseUrl}/api/Tenants`);
  }
}

但是在派生服务中执行构造函数后,属性tenentGuid仍然未定义。

export class TasksService extends BaseApiService<TaskModel> {
  constructor(private httpClient: HttpClient) {
    super(httpClient);
  }

  public list(): Observable<TaskModel[]> {

   return this.httpClient.get<TaskModel[]>(this.generateUrl(), {params: {tenantguid: this.tenantGuid}})
  }

}

我知道这与异步相关,但我不知道如何以另一种方式实现结果。

任何建议将不胜感激)

4

2 回答 2

1

也许更像这样:

注意:未检查语法。

基类

export class BaseApiService<T> implements OnDestroy {

  protected tenantGuid$ = this.http.get<string>(`${this.baseUrl}/api/Tenants`).pipe(
     shareReplay(1)
  );
}

班级

export class TasksService extends BaseApiService<TaskModel> {
  constructor(private httpClient: HttpClient) {
    super(httpClient);
  }

  public list$ = this.tenantGuid$.pipe(
        switchMap(tenantguid => 
        this.httpClient.get<TaskModel[]>(this.generateUrl(), {params: {tenantguid: this.tenantGuid}})
  ))
 }

使用声明性方法,您可以定义提供 GUID 的流。通过 shareReplay 对其进行管道传输,以便将值重播到使用它的任何其他流。

然后在类中,当发出一个 GUID 值时,获取相关数据。如果你的 UI 使用异步管道绑定到 list$,它会在返回时自动更新检索到的数据。

更新:

您还可以使用路由解析器来确保在路由到您的第一条路由之前检索您的 GUID。但这可能会导致您的应用程序启动延迟。

于 2019-12-26T20:56:58.137 回答
1

您可以使用rxjs中的Subject来处理异步调用。收到后您必须致电list()guid

export class BaseApiService<T> implements OnDestroy {

  private subscription: Subscription;
  protected tenantGuid: string;

  protected guidChange: Subject<void> = new Subject<void>()

  constructor(private http: HttpClient) {
     this.subscription = this.getGuid().subscribe(data => {
        this.tenantGuid = data;
        this.guidChange.next(); // emit guid received event
     });
  }

  private getGuid(): Observable<string> {
    return this.http.get<string>(`${this.baseUrl}/api/Tenants`);
  }
}

派生类

export class TasksService extends BaseApiService<TaskModel> {
  constructor(private httpClient: HttpClient) {
    super(httpClient);
    this.guidChange.subscribe(()=> {
      this.list(); // by now guid should be set
    })
  }

  public list(): Observable<TaskModel[]> {

   return this.httpClient.get<TaskModel[]>(this.generateUrl(), {params: {tenantguid: this.tenantGuid}})
  }

}
于 2019-12-26T20:57:58.030 回答