我怎样才能更新我的 Angular2 DatePipe 格式的日期?
How can I get my Angular2 DatePipe-formatted Date to update?
问题示例:http://plnkr.co/edit/7FeRoyyqDnjXpV9Q9Vpy?p=preview
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
似乎管道触发更新不是在更新 linked 对象之后,而是在更新对象的 link 之后。
您可以通过重新分配 this.myDate 来修复它,如下所示:
this.myDate = new Date(this.myDate.setMonth(this.myDate.getMonth() + 1));
您需要使用新的日期参考重新分配日期变量。
this.myDate = new Date(this.myDate.setMonth(this.myDate.getMonth() + 1));
如文档中所述
this pipe is marked as pure hence it will not be re-evaluated when the input is mutated. Instead users should treat the date as an immutable object and change the reference when the pipe needs to re-run
它不起作用,因为 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 及其 markForCheck()
方法来解决 - 这个会更有效率。
或者如 Dmitry 所说,每次要更改数据时只需创建新的日期对象。
问题示例:http://plnkr.co/edit/7FeRoyyqDnjXpV9Q9Vpy?p=preview
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
似乎管道触发更新不是在更新 linked 对象之后,而是在更新对象的 link 之后。
您可以通过重新分配 this.myDate 来修复它,如下所示:
this.myDate = new Date(this.myDate.setMonth(this.myDate.getMonth() + 1));
您需要使用新的日期参考重新分配日期变量。
this.myDate = new Date(this.myDate.setMonth(this.myDate.getMonth() + 1));
如文档中所述
this pipe is marked as pure hence it will not be re-evaluated when the input is mutated. Instead users should treat the date as an immutable object and change the reference when the pipe needs to re-run
它不起作用,因为 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 及其 markForCheck()
方法来解决 - 这个会更有效率。
或者如 Dmitry 所说,每次要更改数据时只需创建新的日期对象。