web-dev-qa-db-ja.com

Angular 2 Date deserialization

Angular 2アプリケーションがあります。サービスは、次のような結果を返すAPIからデータを要求します。

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

私のAngular 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()が呼び出された時点ではわからないためだと思いますか?または私は完全に何か他のものを見逃していますか?これに対する修正または回避策はありますか?

22
rcarrington

文字列フィールドを日付1にマップします。

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;
}
22

dateパイプは、文字列値ではなくDate値のみを受け入れます。

JSONで日付を変換する方法については、 TypeScriptのjson ResponseからDateオブジェクトを取得する方法 を参照してください。

または、独自の文字列から日付への変換パイプを作成できます

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

そして、それを次のように使用します

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

ヒント:使用する@Component(...)デコレータの_pipes: [StringToDate]_にパイプを追加することを忘れないでください。

こちらもご覧ください

6

それがあなたのために働くなら、私の例を試してみてください。そして、ここに Date および Pipe のドキュメントがあります。

<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
3
Ajay Gupta

JSONは日付仕様を提供しないため、シリアル化/逆シリアル化の方法次第です。

JSON.parsereviverパラメーターを使用できます。

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
kemsky