2016-04-17 60 views
17

我有一個Angular 2應用程序。服務是從返回的結果就像一個API請求數據如下:Angular 2日期反序列化

{ 
    "data":[ 
     {"id":1,"timestamp":"2016-04-17T19:52:53.4510935+01:00","sourceDatabaseServer":"127.0.0.1","sourceDatabaseName":"Database1","targetDatabaseServer":"192.168.99.101","targetDatabaseName":"Database2"}, 
     {"id":2,"timestamp":"2016-04-17T19:52:53.4510935+01:00","sourceDatabaseServer":"127.0.0.2","sourceDatabaseName":"Database3","targetDatabaseServer":"192.168.99.102","targetDatabaseName":"Database4"}, 
     {"id":3,"timestamp":"2016-04-17T19:52:53.4510935+01:00","sourceDatabaseServer":"127.0.0.3","sourceDatabaseName":"Database5","targetDatabaseServer":"192.168.99.103","targetDatabaseName":"Database6"} 
    ] 
} 

我的角2服務看起來是這樣的(我剪的錯誤處理,簡潔,因爲我們是幸福的道路上這裏) :

getList() : Observable<SomeModel[]> { 
    return this._http.get(this._getListUrl).map(this.extractData); 
} 

private extractData(res: Response) { 
    return res.json().data || {}; 
} 

和我的組件是這樣的:

results: SomeModel[]; 
errorMessage: string; 
ngOnInit() { 
    this._someService.getList() 
     .subscribe(
     results => this.results = results, 
     error => this.errorMessage = <any>error); 
} 

和我的模型是這樣的:

export class SomeModel { 

    constructor(
     public id: number, 
     public timestamp: Date, 
     public sourceDatabaseServer: string, 
     public sourceDatabaseName: string, 
     public targetDatabaseServer: string, 
     public targetDatabaseName: string 
    ) { } 
} 

一切看起來不過是工作,當我嘗試使用DatePipe像這樣{{item.timestamp | date:'short'}}顯示時間戳應用吹了以下錯誤消息:

Invalid argument '2016-04-17T19:40:38.2424240+01:00' for pipe 'DatePipe' in [{{result.timestamp | date:'short'}} 

經過一番調查後相信時間戳是不實際被轉換爲Date類型,而是被設置爲string。我猜這是因爲Date類型在當時不知道Response.json()被稱爲?還是我完全錯過了別的東西?有沒有修復或解決這個問題?

+1

當你做一個'以.json()'不會改變一個字符串(即使是在一些日期格式)和實際日期對象。它將繼續作爲一個字符串。所以你需要'new Date(herePassTheString)' – arg20

+1

如果你只顯示它,Angular 2中的DatePipe現在可以使用ISO字符串格式。 https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html我不知道這是否一直如此,但現在。 ;) – Derrick

回答

18

我將字符串字段映射到一個日期之一:

getList() : Observable<SomeModel[]> { 
    return this._http.get(this._getListUrl).map(this.extractData); 
} 

private extractData(res: Response) { 
    var data = res.json().data || []; 
    data.forEach((d) => { 
    d.timestamp = new Date(d.timestamp); 
    }); 
    return data; 
} 
+0

是的,最好的辦法......之後的一切都是一致的!這裏是另一種格式:-),''''d.timestamp = new Date(parseInt(d.timestamp.substr(6)));' –

+0

爲什麼我在這一行上得到一個錯誤:var data = res.json( ).data || [];當我嘗試使用此代碼? 「Promise 類型上不存在屬性數據」 – Aaron

5

date管只接受Date值不是字符串值。

請參閱How to get Date object from json Response in typescript瞭解如何在JSON中轉換日期。

或者你可以創建自己的字符串到日期轉換管

@Pipe({name: 'toDate'}) 
export class StringToDate implements PipeTransform { 
    transform(value, [exponent]) : number { 
    if(value) { 
     return new Date(value); 
    } 
    } 
} 

,然後使用它像

{{item.timestamp |toDate | date:'short'}} 

提示:不要忘記管道添加到pipes: [StringToDate]@Component(...) decorater你想要使用它。

+0

這實際上是一個angularJS(角度1)響應。 Angular 2現在支持多種格式,包括正確的ISO字符串格式。 https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html – Derrick

+0

這不是一個AngularJS 1答案(不知道1.x),但它幾乎是一歲,一個從那時起很多變化。當我回來時我會更新。謝謝你的提示。 –

+0

啊,對不起。你是對的。我現在在那裏看到你的@Pipe。我實際上很困惑,因爲角1的文檔是引用鏈接。 https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html – Derrick

1

見JSON不提供任何日期規範,所以它是完全取決於它是如何序列化/反序列化。

你可以使用reviver參數JSON.parse:如果你的工作

this._http.get(this._getListUrl).map(res => JSON.parse(res.text(), this.reviver)); 

reviver(key, value):any 
{ 
    if('timestamp' === key){ 
     //you can use any de-serialization algorithm here 
     return new Date(value); 
    } 
    return value; 
} 
2

試試我的榜樣。這裏是DatePipe的文檔。

<span>Date : {{announcement.createdAt | date:'EEE, d MMM,y'}}</span> 
<span>Time : {{announcement.createdAt | date:'shortTime'}}</span> 

輸出:

Date : Tue, 20 Dec,2016  
Time : 2:22 PM