Angular2 将 json 结果转换为接口
Posted
技术标签:
【中文标题】Angular2 将 json 结果转换为接口【英文标题】:Angular2 cast a json result to an interface 【发布时间】:2016-04-03 15:35:01 【问题描述】:使用 Angular2 和 typescript,我从 webApi 返回 JSON,我需要将它放入特定类型的数组中。我不知道如何将 json 转换为我需要的接口。
我的类型是这个界面:
export interface Country
Id: number;
Name: string;
我的模拟返回这个数组:
export var COUNTRIES: Country[] = [
"Id": 11, "Name": "US" ,
"Id": 12, "Name": "England" ,
"Id": 13, "Name": "Japan"
];
这是我的代码: country.service.ts
@Injectable()
export class CountryService
private _http = null;
constructor(http: Http)
this._http = http;
getCountries()
return Promise.resolve(COUNTRIES);
然后我用这个来称呼它:
export class CountryPickerComponent
public countries: Country[];
constructor(private _countryService: CountryService)
getCountries()
this._countryService.getCountries().then(data => this.setData(data));
setData(data)
//this.countries = data;
this.countries = JSON.parse(data);
var q = 1;
ngOnInit()
this.getCountries();
如您所见,我有一个名为 countries 的类变量,它是 Country 接口的数组。这按预期工作。 (我知道我不需要那个 setData 方法——它是用来调试的)
接下来,我将服务更改为返回此 json 的 wepApi 调用。
"["name":"England","id":1,"name":"France","id":2]"
我将服务中的 getCountries 方法更改为:
getCountries()
return new Promise(resolve=>
this._http.get('http://localhost:63651/Api/membercountry')
.subscribe(data => resolve(data.json()))
);
使用 JSON.parse,我将它转换为一个数组,然后我可以在 angular2 中使用它。有用。它使用数据创建数组。但它不是实现 Country 接口的数组。
请注意,JSON 中的字段名称都是小写的,但接口属性以大写开头,我对接口进行了编码。结果,当我得到真正的 json 时,它不起作用。有没有办法将它“投射”到界面,这应该会引发错误并让我知道有什么问题?
很多例子在get中使用map如下所示:
getCountries()
var retVal;
return new Promise(resolve=>
this._http.get('http://localhost:63651/Api/membercountry')
.map(ref => ref.json())
.subscribe(data => resolve(data.json()))
);
我找不到这方面的文档。当我尝试它时,我永远不会得到数据,但没有错误。没有编译错误,也没有运行时错误。
【问题讨论】:
如果你使用angular 2 beta
,map
在Observable
中不可用,从http.get()
返回,而是subscribe
直接在Observable
上使用。
【参考方案1】:
您可以对 JSON.parse 创建的对象所期望的接口进行类型断言。
this.http.get('http://localhost:4200/').subscribe((value: Response) =>
let hero = <ServerInfo>value.json();
);
但是,如果服务器出于 2 个原因向您发送坏对象,这不会导致任何错误。
在编译时,转译器不知道服务器将发送什么。
在运行时,所有类型信息都会被删除,因为所有内容都被编译为 javascript。
【讨论】:
在运行时它是无类型的,在编译时我们不知道 api 将返回什么。这是有道理的,但它并没有真正的帮助。我想我们需要先了解 json 并相应地构建我们的对象。 @user1617407 完全正确。你不能投射到一个未知的接口。你可以投射到任何接口,但这也无济于事。【参考方案2】:Viktor Savkin 针对这种情况有一个library to do runtime checking of types,但它不适用于接口,因为 Typescript 不会在接口上导出运行时信息。有一个关于这个here的讨论。
有两种可能的解决方案:
如果您知道来自 api 的数据是正确的形状,并且您只是想向您的 IDE/编译器提供有关此形状的信息,您可以按照 toskv 的回答进行转换。 如果您不确定 api 并希望您的应用程序在数据形状错误时抛出异常,您将不得不实施自己的检查。这有点开销,但对于大型应用程序来说非常值得。一般来说,我认为 Typescript 的类型不仅仅是一个严格的类型系统,而是编译器提示 - 毕竟它必须编译为无类型语言。
【讨论】:
以上是关于Angular2 将 json 结果转换为接口的主要内容,如果未能解决你的问题,请参考以下文章
将数据库中查询的结果转换为json, 然后调用接口的方式返回json
Angular 2 - 将 JSON 解析为具有计算属性的类