在 Angular 5 服务中处理 url 变量的最简单方法

Easiest way to handle url variables in Angular 5 Services

我正在使用 Angular CLI 1.5.4 / Angular 5.0.4(起始代码由 Angular CLI 生成)。应用程序的状态高度依赖于当前用户的元数据,并且在服务 类 中执行我的大部分 HTTP 请求需要我传递 URL 变量,例如 /api/company/{companyId}/some-resource/1/api/users/{userId}/ui-settings/some-ui-option .

我的方法:用户的对象在登录后使用 PrincipalService 存储,我可以在应用程序的任何地方请求它 (PrincipalService.getUser() : Promise<UserIdentity>)。

用户返回为 Promise,因为我实际上可能需要发送 Http 请求来加载用户数据。使用用户 ID 的示例服务:

@Injectable()
export class UserUiSettingsService {

  constructor(private http: HttpClient,
              private principal: PrincipalService) { }

  private urlUserGroupingTableUISettings(): Promise<string> {
    return new Promise<string>((resolve, reject) => {
      this.principal.getUser().then(
        user=> resolve(`${environment.httpBaseUrl}users/${user.id}/ui-settings/document-path-grouping`),
        error=>reject(error)
      );
    });
  }

  getUsersGroupingTableUISettings() : Promise<DocumentPathTableUISettings> {
    return new Promise<DocumentPathTableUISettings>((resolve, reject) => {
      this.urlUserGroupingTableUISettings().then(
        url=> this.http.get<DocumentPathTableUISettings>(url).toPromise().then(
          data=>resolve(data),
          error=>reject(error)
        ),
        error=>reject(error)
      );
    });
  }
  ...
}

所以要真正调用 getUsersGroupingTableUISettings() 中的 http 方法,我需要创建一个新的 Promise 并首先解析 User 对象,然后我才能开始请求。

我的问题是嵌套,我真的需要嵌套这些请求并以如此丑陋的方式等待每次成功吗?我能否以更方便的方式执行此操作(想象一下我的方法如果我需要加载 3-4 种不同的东西,而不仅仅是用户的,可能还有一些公司数据)?

您可以使用三种方法:

  1. 使用 await 关键字。
  2. 使用承诺链。
  3. Observable.mergeMap.map 运算符

前两个代码示例:

1.

private async urlUserGroupingTableUISettings(): Promise<string> {        
  const user = await this.principal.getUser();
  return `${environment.httpBaseUrl}users/${user.id}/ui-settings/document-path-grouping`;
}

getUsersGroupingTableUISettings() : Promise<DocumentPathTableUISettings> {    
  const url = await this.urlUserGroupingTableUISettings()
  return await this.http.get<DocumentPathTableUISettings>(url).toPromise();
}

2.

private urlUserGroupingTableUISettings(): Promise<string> {        
  return this.principal.getUser().then(
    user=>`${environment.httpBaseUrl}users/${user.id}/ui-settings/document-path-grouping`
  );
}

getUsersGroupingTableUISettings() : Promise<DocumentPathTableUISettings> {    
  return this.urlUserGroupingTableUISettings()
      .then(
          url=>this.http.get<DocumentPathTableUISettings>(url).toPromise()
      );
}

3.

使用可观察对象,最简单的方法是:

getUsersGroupingTableUISettings() : Observable<DocumentPathTableUISettings> {
   return this.principalService.getUserObservable().flatMap(
        user=>this.http.get<DocumentPathTableUISettings>(`${environment.httpBaseUrl}users/${user.id}/ui-settings/document-path-grouping`)
    );
}