2016-11-10 85 views
0

样的问题:http://plnkr.co/edit/7FeRoyyqDnjXpV9Q9Vpy?p=preview如何获取我的Angular2 DatePipe格式的日期以更新?

import {Component, NgModule} from '@angular/core' 
import {BrowserModule} from '@angular/platform-browser' 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2>{{myDate}}</h2> <!-- THIS UPDATES AS EXPECTED --> 
     <h2>{{myDate | date: 'longDate'}}</h2> <!-- THIS DOES NOT --> 
     <a (click)="prevMonth()" href="javascript:;">Previous Month</a> 
     <a (click)="nextMonth()" href="javascript:;">Next Month</a> 
    </div> 
    `, 
}) 
export class App { 
    myDate: Date; 
    constructor() { 
    this.myDate = new Date(); 
    } 

    nextMonth() { 
    this.myDate.setMonth(this.myDate.getMonth() + 1); 
    } 

    prevMonth() { 
    this.myDate.setMonth(this.myDate.getMonth() - 1); 
    } 
} 

@NgModule({ 
    imports: [ BrowserModule ], 
    declarations: [ App ], 
    bootstrap: [ App ] 
}) 
export class AppModule {} 

当我通过我的变量,而无需使用任何管道,它更新符合市场预期。但是同一个变量的DatePipe格式副本不会更新。管道是否仅更新观测值?或者我可以使用这种标准的日期类型,并期望它实时更新?

我没有看到DatePipe API中的任何内容表明这是预期的行为,但我已经缩小到只有DatePipe可能以这种方式影响行为的程度。 https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html

回答

2

它不工作,因为Angular2的DatePipe是有状态(在pure属性在装饰设置为true功能)。有状态管道仅在给定对象上应用一次。您可以更改管道定义(当然不是A2源)或者做出某些事情来强制更改数据。

所以第一种方式来解决这个问题是创建并使用新的无国籍管:

@Pipe({name: 'myDate', pure: false}) 
export class MyDatePipe implements PipeTransform { 
    transform(value: any, pattern: string = 'mediumDate'): string { 
    return (new DatePipe()).transform(value, pattern); 
    } 
} 

我已经准备了一个plnkr example。 它很简单且可重复使用,所以我会推荐这个小数据解决方案。

虽然也可以在每次更新日期后使用ChangeDetector及其方法解决,但这种方法效率更高。或者如德米特里所说,每当你想改变数据时只需要创建新的日期对象。

1

看起来像管道触发更新不是在更新链接对象后,而是更新对象链接后触发更新。

您可以通过重新分配this.myDate像下面修复:

this.myDate = new Date(this.myDate.setMonth(this.myDate.getMonth() + 1));

1

您需要重新分配新的日期的引用日期变量。

this.myDate = new Date(this.myDate.setMonth(this.myDate.getMonth() + 1));

作为文档

此管被标记为纯因此它不会被当输入被突变重新评估中所述。相反,用户应该把日期作为一个不可变对象,并改变基准当管道需要重新运行