将httpClient答案转换为模型对象[Angular 6]

Col*_*lja 13 typescript angular angular6

我有一个关于Angular 5 httpClient的问题.

这是一个带有方法foo()的模型类,我希望从服务器接收

export class MyClass implements Deserializable{
  id: number;
  title: string;

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

  foo(): string {
    // return "some string conversion" with this.title
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我的服务请求:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { MyClass } from './MyClass';

@Injectable({
  providedIn: 'root',
})
export class MyClassService {

  constructor(private http: HttpClient) {
  }

  getMyStuff(): Observable<MyClass[]> {
    // this is where I hope to convert the json to instances of MyClass
    return this.http.get<MyClass[]>('api/stuff')
  }
}
Run Code Online (Sandbox Code Playgroud)

我的问题

当我向服务部门询问MyClass我获取数据的实例时,我无法{{ item.foo() }}在模板中运行.此外,当我console.log()typeof它在服务接收的邮件,我根本没有看到的对象的实例MyClass.

我究竟做错了什么?我认为写作this.http.get<MyClass[]>('api/stuff')会进行转换.

任何提示?先感谢您!

Twi*_*her 24

这样做时,TypeScript只执行"类型断言".这意味着您告诉TypeScript您的对象是类型的MyClass,但该对象实际上并不是MyClass运行时的实例.为了调用模型对象中定义的函数,您必须在模型类中定义构造函数,如下所示:

constructor(obj?: any) {
    Object.assign(this, obj);
}
Run Code Online (Sandbox Code Playgroud)

然后在您的服务中添加如下映射:

http.get<MyClass>('/my-class').pipe(
      map(res => new MyClass(res))
Run Code Online (Sandbox Code Playgroud)

注意:上面的代码是RxJS 6样式,我不知道你使用的是哪个版本

  • 不客气,我个人喜欢构造函数,`Deserialize`接口是另一个合适的选择 (2认同)
  • 仅当`MyClass`没有复杂的成员时(例如类型为Date的成员或其他类),这才起作用 (2认同)
  • @ Jota.Toledo是的,这可以通过为这些属性定义setter来解决 (2认同)