2015-12-29 69 views
23

使用Angular2和typescript,我从webApi返回JSON,并且需要将其转换为特定类型的数组。我无法弄清楚如何将json转换为我需要的接口。Angular2将json结果转换为接口

我喜欢的类型是这样的接口:

我的模拟返回此阵:

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(); 
    } 
} 

正如你所看到的,我有一个名为country的类变量,它是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使用地图,如下图所示:

getCountries() { 
     var retVal; 

     return new Promise(resolve=> 
      this._http.get('http://localhost:63651/Api/membercountry') 
       .map(ref => ref.json()) 
       .subscribe(data => resolve(data.json())) 
     ); 
    } 

我找不到这个文件。当我尝试它时,我从来没有收到数据,但没有错误。没有编译错误和没有运行时错误。

+1

如果您使用的是'angular 2 beta','map'在'http.get()'返回的'Observable'中不可用,而直接在'Observable'上使用'subscribe'。 – TheKojuEffect

回答

12

您可以对JSON.parse创建的对象期望的接口执行类型断言。

this.http.get('http://localhost:4200/').subscribe((value: Response) => { 
    let hero = <ServerInfo>value.json(); 
    }); 

但是,如果服务器由于2种原因向您发送了不良对象,则这不会导致任何错误。

在编译时,转译器不知道服务器将发送什么。

在运行时,所有类型的信息都被删除,因为所有的东西都被编译为 javascript。

+1

在运行时它是无类型的,在编译时我们不会看到api会返回什么。这是有道理的,但它并没有真正的帮助。我想我们需要首先了解json并相应地构建我们的对象。 –

+0

@ user1617407正好。你不能投到一个未知的界面..你可以投到任何界面,但这也没有任何帮助。 – toskv

3

尤Savkin有这种情况library to do runtime checking of types但由于打字稿不输出接口上运行时信息不与接口工作。有关于这个here的讨论。

有两种可能的解决方案:

  • 如果你知道从API来,是正确的形状中的数据,而你只是希望给你的IDE /关于这个形状的编译器的信息,你可以投根据toskv的答案。
  • 如果您不确定api并希望您的应用程序在数据是错误的形状时抛出,则必须执行自己的检查。这是一个开销,但它对于更大的应用程序来说是非常值得的。

一般来说,我认为Typescript的类型不仅仅是一个严格的类型系统 - 它必须编译成一个无类型的语言。