Angular 5,HttpClient 不会使用类的构造函数



我有一个服务和一个组件。

一些.service.ts

import { Injectable } from '@angular/core';
import { HttpClient} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { SomeClass } from '../model/some.class';
@Injectable()
export class SomeService {
constructor(private http: HttpClient) {}
getData(): Observable<SomeClass[]> {
let url = 'someUrlEndpoint';
let results = this.http.get<SomeClass[]>(url);
return results;
}
}

some.component.ts

import { SomeService } from './service/some.service';
import { SomeClass } from './model/some.class';
export class SomeComponent {
someClass: SomeClass[];
constructor(private someService: SomeService)
ngOnInit() {
this.getData()
}
getData() {
this.someService.getData()
.subscribe(res => this.someClass = res);
}
}

一些.class.ts

export class SomeClass {
title: string;
status: string;
numberOfPersons: number;
persons: string;
...
constructor(json: any = "") {
this.title = json.title;
this.status = getStatus(json.status);
this.numberOfPersons = getNumberOfPersons(json.persons);
this.persons = json.persons;
...
}
getStatus(value: number) {
let status = StatusCase.ongoing;
if(value == 1) {status = StatusCase.done}
if(value == 2) {status = StatusCase.completeWithDeviations}
if(value == 3) {status = StatusCase.aborted}
return status;
}
getPersons(value: string) {
let persons = 0;
get persons splitted by comma, count it up and return
return persons;
}
}
export enum StatusCase {
ongoing = "Ongoing";
aborted = "Aborted";
completeWithDeviations = "Complete with deviations";
done = "Done";
}

我能够获取数据,但不是以我想要的方式。

现在,由于 httpClient 不返回 SomeClass 的实例,因此它不会通过构造函数,并且应用程序将无法获得所需的正确数据。 那么"新的SomeClass(data("在哪里适合呢?是否可以以构建httpClient的方式进行操作?或者我必须获取非类型化数据 (json( 并执行 for 循环以传统方式填充 someClass:SomeClass[]?

或者是否有另一种更智能的方法来填充计算属性? 使用拦截器操作响应中的数据?似乎响应上的拦截器仅用于错误。

.get<SomeClass[]>不执行任何操作。它仅在开发过程中有用。您可以运行映射运算符并返回类的实例。

您可以使用像class-transformer这样的库将HTTP响应纯JavaScript映射到类对象中:

// assuming that your json response from the http call is an array
const obs: Observable<SomeClass[]> = this.http.get(url).map(res => 
plainToClass(SomeClass, res));

short answer:

不是没有办法做到的。下面的解释,或者只是跳到这个问题的解决方案,尽管您在问题中概述了它。


长答案

当您在此处使用泛型时.get<SomeClass[]>()您将向打字稿提供更多信息,以帮助在转译时(静态 + 强类型(实现代码正确性。请记住,Typescript 只是 JS 的一个超集,所以当运行时发生时,无法真正知道你有一个类。因为 JS 中的类本身只是原型模型的语法糖。

所以引擎盖下仍在发生的事情JSON.parse(jsonStr)..由于鸭子类型,此对象(如果您的类正确匹配传入的 JSON(将能够按原样满足要求。如果你想实例化一个类,你必须自己做。


Solution

我们可以将密钥分散到实例的简单方法

this.http.get<SomeClass[]>(url)
.pipe( 
map( someClasses => 
someClasses.map( someClass => Object.assign(new SomeClass(), { ...someClass } ) 
) 
)
.subscribe( someClasses => results = someClasses);

or constructor route..附言 你不需要在你的构造函数中使用any

export class SomeClass {
constructor(someClass: SomeClass) {
this.title = someClass.title;
this.status = this.getStatus(someClass.status);
//...
}
getStatus(value: number) {
//...
}
}
<小时 />
this.http.get<SomeClass[]>(url)
.pipe( 
map( someClasses => 
someClasses.map( someClass => new SomeClass(someClass) ) 
) 
)
.subscribe( someClasses => results = someClasses);

相关内容

最新更新