角度转换 HttpClient 响应 - 类或接口

per*_*tor 6 angular angular5 angular6

我看到了两种将响应转换为我们的自定义数据模型的方法。

界面

export interface User {
  id: number;
  name: string;
  more_complex_object: // so I am not sure how do this in right way. pass here another interface 
  //or just a object like {id: '', name: ''}. I show how to do this in class way...
}
Run Code Online (Sandbox Code Playgroud)

并在服务中:

return this.http.get<User>...
Run Code Online (Sandbox Code Playgroud)

没关系,不需要做更多的事情。

班级

export interface Deserializable {
  deserialize(input: any): this;
}

export class ComplexModel implements Deserializable {
  field1: string;
  field2: number;
  field3: number;

  deserialize(input: any): this {
    Object.assign(this, input);
    return this;
  }
}

export class User implements Deserializable {
 id: number;
 name: string;
 complex: ComplexModel;

 deserialize(input: any): this {
   Object.assign(this, input);
   this.complex = new ComplexModel().deserialize(input.complex));
   return this;
 }
}
Run Code Online (Sandbox Code Playgroud)

并在服役中

return this.http.get('/users/id/').pipe(
  map(user => new User().deserialize(user))
);
Run Code Online (Sandbox Code Playgroud)

正如我们在类方法中看到的,我们必须手动创建一个对象。对于像上面这样的对象来说没问题,但是当我们有更复杂的对象或对象数组时,我们必须这样做:

return this.http.get('/users').pipe(
  map(users => {
    if (users instanceof Array) { // <- to avoid 'object has no method map' error
      return users.map(user => {
        return new User().deserialize(user);
      });
    }
  })
);
Run Code Online (Sandbox Code Playgroud)

在类方式中,我们有更复杂的代码。最后,问题是:

知道如何尽可能地做到最好吗?哪种方法最适合您,为什么?

接口方式看起来更漂亮,但是我们没有“真实的对象”,所以我们不能使用类方法等,对吧?

在类方式中我们得到了一个真实的对象,但是它有那么必要吗?

小智 5

Shyam Seshadri 的《Angular Up and Running》一书中对此有解释。\n我直接引用《Ch9 Making HTTP Calls in Angular》一书第 178 页:

\n\n

"需要注意的一件重要事情是,HttpClient 可以为您提供跨代码的类型保证。我们在 getStocks() 和toggleFavor\nite() 方法中利用此功能。\n这样做的一个影响是我们需要更改我们的 stock.ts 从 TypeScript 类到\nTypeScript 接口。\n这是为什么?虽然我们不需要\xe2\x80\x99,Angular 会将响应主体简单地转换为我们定义的类型。但是 TypeScript ( \n它下面的 ECMAScript)没有很好且简单的方法来将简单的普通 JavaScript 对象转换为典型的 JavaScript/TypeScript 类对象。\n这意味着\n虽然我们来自 StockService 的响应将具有该类的所有属性\ nStock,它没有可用的函数(特别是 isPositiveChange())。\n我们可以编写一个转换器,但只有在非常特定的情况下才值得。\n更容易利用 TypeScript 来实现类型安全并与其他封装方式\n(无论是在组件级别,还是作为 Angular 服务)。”

\n\n

更多解释请参考书本

\n


Joe*_*nna 0

我使用接口。尚未使用 Angular 中的类。关于这个问题有一篇很好的文章:Classes vs Interfaces in TypeScript也许阅读它会帮助您决定使用哪一个。