2016-04-17 29 views
17

Tôi có ứng dụng Angular 2. Dịch vụ yêu cầu dữ liệu từ api trả về kết quả như sau:Góc 2 Ngày deserialization

{ 
    "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"} 
    ] 
} 

Dịch vụ Angular 2 của tôi trông như thế này (Tôi đã cắt lỗi xử lý ngắn gọn khi đang trên đường hạnh phúc) :

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

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

và thành phần của tôi như thế này:

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

và mô hình của tôi như thế này:

export class SomeModel { 

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

Mọi thứ trông giống như nó đã làm việc tuy nhiên khi tôi cố gắng để hiển thị dấu thời gian bằng cách sử dụng DatePipe như vậy {{item.timestamp | date:'short'}} ứng dụng thổi lên với thông báo lỗi sau:

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

Sau một số cuộc điều tra tôi tin rằng dấu thời gian không phải là thực sự đang được chuyển đổi thành loại Date nhưng thay vì chỉ được đặt là string. Tôi đoán điều này là do loại Date không được biết tại thời điểm Response.json() được gọi? hoặc tôi thiếu cái gì khác hoàn toàn? Có một sửa chữa hoặc làm việc xung quanh cho điều này?

+1

Khi bạn làm một '.json() 'rằng sẽ không chuyển đổi một chuỗi (ngay cả khi nó trong một số định dạng ngày) đến một đối tượng ngày thực tế. Nó sẽ tiếp tục là một chuỗi. vì vậy bạn cần phải làm 'new Date (herePassTheString)' – arg20

+1

Nếu bạn chỉ hiển thị nó, DatePipe trong Angular 2 bây giờ có thể sử dụng định dạng chuỗi ISO. https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html Tôi không biết nếu điều này đã luôn luôn được các trường hợp, nhưng nó là ngay bây giờ. ;) – Derrick

Trả lời

18

tôi sẽ lập bản đồ các lĩnh vực chuỗi đến một ngày một:

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

Đúng, cách tiếp cận tốt nhất ... mọi thứ sau đó là liên kết rồi! Và đây là một định dạng thay thế :-), 'd.timestamp = new Date (parseInt (d.timestamp.substr (6)));' –

+0

Tại sao tôi gặp lỗi trên dòng này: var data = res.json () .data || []; khi tôi cố gắng sử dụng mã này? "Dữ liệu thuộc tính không tồn tại trên loại Promise " – Aaron

5

Các ống date chỉ chấp nhận Date giá trị không giá trị chuỗi.

Xem How to get Date object from json Response in typescript để biết cách chuyển đổi ngày trong JSON.

Hoặc bạn có thể tạo riêng chuỗi-to-date ống chuyển đổi của bạn

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

và sau đó sử dụng nó như

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

Gợi ý: đừng quên để thêm các đường ống để pipes: [StringToDate] trên @Component(...) decorater nơi bạn muốn sử dụng.

cũng

+0

Đây thực sự là một phản ứng góc cạnh (góc 1). Angular 2 giờ đây hỗ trợ nhiều định dạng khác nhau, bao gồm định dạng chuỗi ISO chính xác. https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html – Derrick

+0

Nó không phải là một câu trả lời AngularJS 1 (không biết 1.x), nhưng nó gần một tuổi và một rất nhiều đã thay đổi kể từ đó. Tôi sẽ cập nhật khi tôi trở lại. Cảm ơn ghi chú. –

+0

Ah, xin lỗi. Bạn nói đúng. Tôi thấy @Pipe của bạn ở đó ngay bây giờ. Tôi đã thực sự bối rối vì các tài liệu cho góc 1 là các liên kết ref. https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html – Derrick

1

Xem JSON không cung cấp bất kỳ đặc điểm kỹ thuật ngày, vì vậy nó là hoàn toàn tùy thuộc vào cách nó là serialized/deserialized.

Bạn có thể sử dụng reviver tham số của 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

Hãy thử ví dụ của tôi nếu công việc của mình cho bạn. Và đây là tài liệu cho DatePipe.

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

Output:

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