【问题标题】:Converting from HttpModule to HttpClientModule从 HttpModule 转换为 HttpClientModule
【发布时间】:2017-09-20 20:45:02
【问题描述】:

Angular 正在从 HttpModule 转换为 HttpClientModule 并弃用前者,详见Difference between HTTP and HTTPClient in angular 4?

然而,https://angular.io/tutorial/toh-pt6 的 Angular 教程使用 HttpModule,而https://angular.io/guide/http 的基础信息使用 HttpClientModule,详见 https://github.com/angular/angular/issues/19280。本教程使用内存服务器,而基础使用真正的 Web 服务器,使比较变得更加困难。

我尝试使用真实的 Web 服务器在 Angular 教程代码中从 HttpModule 切换到 HttpClientModule,并让某些部分正常工作,但其他部分不工作。似乎可以将 hero.services.ts 中的 getHeroes 方法之一从

  getHeroes(): Promise<Hero[]> {
    return this.http.get(this.heroesUrl)
      .toPromise()
      .then(response => response.json().data as Hero[])
      .catch(this.handleError);
  }

  getHeroes(): Promise<Hero[]> {
    return this.httpClient.get(this.heroesUrl)
      .toPromise()
      .then(data => data['heroes'] as Hero[])
      .catch(this.handleError);
  }

虽然可能有一些方法可以改进,这个版本可能有我还没有发现的问题。

但我在 hero-search.service.ts 中没有看到搜索方法的等效项

  search(term: string): Observable<Hero[]> {
    return this.http
      .get(`api/heroes/?name=${term}`)
      .map(response => response.json().data as Hero[]);
  }

应该可以不用map,但是你不能使用上面的方法,因为有一个Observable而不是Promise,你会得到如下错误:

Type 'Observable<Object>' is not assignable to type 'Observable<Hero[]>'.

有没有人将 Angular 教程中的 Heroes 演示转换为使用 HttpClientModule 或知道如何转换上面的搜索代码?

【问题讨论】:

    标签: angular http rxjs reactivex angular-httpclient


    【解决方案1】:

    虽然 HttpClient 将 JSON 响应解析为一个对象,但它不知道该对象是什么形状。因此,您可以指定响应的类型:

    return this.http
        .get<{ data: Hero[] }>(`api/heroes/?name=${term}`)
        .map(res => res.data);
    

    请注意,您可以为此创建接口:

    interface ItemsResponse {
      data: Hero[];
    }
    
    return this.http
      .get<ItemsResponse>(`api/heroes/?name=${term}`)
      .map(res => res.data);
    

    如果您怀疑什么类型的响应将是或不想创建界面,那么只需使用any

    return this.http
      .get<any>(`api/heroes/?name=${term}`)
      .map(res => res.data);
    

    TOH-HttpClientModule Example

    另见

    【讨论】:

    • 这解决了问题,如plnkr.co/edit/uW3F0TPLqP9sSA4AdyGu?p=preview 所示。在 hero.service.ts 中,我转而在 getHeroes 等方法中使用类似的语法,而不是上面给出的代码。但我不确定如何处理标题和帖子,并且 create 方法抛出错误“无法在字符串上创建属性 'id'”。对这些部分的建议将不胜感激。
    【解决方案2】:

    重写您的组件,他们在 httpClient 中删除了 response.json,不再需要调用 response.json()。如果数据不是正确的响应名称,请打开控制台并查找返回对象的正确名称。

    search(term: string): Observable<Hero[]> {
    return this.http
      .get(`api/heroes/?name=${term}`)
      .map(response => {
             console.log(response);
             return response['data'] as Hero[]
       });
    
    }
    

    【讨论】:

    • Observable 的对象无法分配给 Observable
    • 可能是你的英雄类有必填字段,而空对象由于必填字段不能成为英雄类。
    • 不是,因为httpClient可以返回两种对象。如果服务器没有返回任何内容,它将返回{}。在订阅中,我们必须编写处理这种情况的逻辑。
    猜你喜欢
    • 2017-12-21
    • 2019-06-19
    • 2018-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多