实现动态时区选择器Angular 2/4/5
问题描述:
我需要在我的Angular 4/5应用程序中构建一个TimeZone选择器。当用户更改时区时,我希望页面上的所有显示时间值立即更新。实现动态时区选择器Angular 2/4/5
我正打算使用:
- momentjs使用
angular2-moment
和angular-moment-timezone
时区的支持。 - 要格式化日期,请使用
amLocal
管道,然后是其他管道。 - 当用户选择不同的时区,我打算叫
moment.tz.setDefault(_timezone)
通过以上的值从被格式化为新的时区了这一点,而目前显示的时间值不会改变。由于输入值没有改变,角度更改检测机制不会更新显示的时间值。
由于性能开销(考虑时区更改不是一个频繁的活动),我不想创建“不纯”管道。
作为后备我可以创建一个管道(或使用现有的),将当前时区作为参数。它确实有效,但我需要将当前时区值传递给每个组件和模板。
我一直无法找到角度变化检测的方法,即使没有值的变化,也会发生变化。
任何建议将受到欢迎。
答
管道不是组件(显而易见),它们没有自己的更改检测机制,但pure
标志除外。所以有两种方法可以达到预期的效果:
-
使用智能不纯管道将跟踪以前的值和以前的格式化结果。角的
AsyncPipe
(这是不纯实际上,如果有另一种方式来这样做,那么我相信这将是由纯)被以这种方式实现:if (value !== this.value || this.timeZoneChanged) { this.value = value; this.formattedValue = ... render value ...; } return this.formattedValue;
您可以在github上浏览
AsyncPipe
源代码。 - 使用自定义组件呈现日期,即自定义
ControlValueAccessor
。
答
例如,当使用例如ngx-translate
时,切换语言意味着获取新的翻译。正如你可以看到here他们使用不纯的管道,正如你所说的暗示性能问题。
我想象的另一种方式是定义一个可用于整个应用程序的组件DateComponent
。这样,而不是在您的html {{ value | formatDate }}
你有<custom-date [date]="new Date()"></custom-date>
。
在您的自定义日期组件将看起来像这样
@Component({
selector: 'custom-date',
template: '<span>{{ formatedDate }}</span>'
})
export class DateComponent {
@Input() date: string;
timezone: string;
formatedDate: string;
constructor(private userService: UserService) {}
ngOnInit(){
this.timezone = this.userService.getTimeZone();
this.updateValue();
this.userService.onTimezoneChange()
.subscribe(timezone => {
this.timezone = timezone;
this.updateValue();
});
}
updateValue() {
// Do your formatting the way you want
this.formatedDate = moment(this.date).tz(this.timezone).format();
}
}
*我一直没能找到一种方式,角度变化检测相信有变化,即使没有*值的变化:是你有:这就是所谓的不纯管道。 –
双重绑定可能是您的最佳选择? –
当你说“不更新显示的时间值”时,你的意思是什么?你的意思是这些值代表“现在”,你希望它们像时钟一样向前跳动?如果是这样,你需要一个某种计时器。 –