【问题标题】:Easiest way to handle url variables in Angular 5 Services在 Angular 5 服务中处理 url 变量的最简单方法
【发布时间】:2018-01-16 10:05:48
【问题描述】:

我正在使用 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 种不同的东西,而不仅仅是用户的,还可能是一些公司数据)?

【问题讨论】:

  • 您有什么理由要使用Promise 而不是Observables
  • @CozyAzure 不,老实说,我是 Angular2 和 RxJS 的新手,所以我不确定。有银弹吗?就像我应该在任何地方都使用Observables 吗?还是BehaviorSubject
  • 不确定我是否会声称它是灵丹妙药,但是是的,observables 有很多运算符可以使代码优雅且易于阅读(有偏见)
  • @CozyAzure 但是我需要订阅/取消订阅才能以相同的嵌套方式生成 url,不是吗?
  • 不,不是。 rxjs 中有 .then() 等价物。

标签: angular rxjs angular2-services


【解决方案1】:

您可以使用三种方法:

  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.

使用 observables,最简单的是:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-16
    • 2018-09-10
    • 2011-09-19
    • 2018-08-11
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    相关资源
    最近更新 更多