2015-12-29 135 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的類型不僅僅是一個嚴格的類型系統 - 它必須編譯成一個無類型的語言。