实现动态时区选择器Angular 2/4/5



我需要在Angular 4/5应用程序中构建一个时区选择器。当用户更改时区时,我希望页面上显示的所有时间值都能立即更新。

我计划使用:

  • momentjs,使用angular2-momentangular-moment-timezone支持时区
  • 要设置日期格式,请使用amLocal管道,然后使用其他管道
  • 当用户选择不同的时区时,我计划呼叫moment.tz.setDefault(_timezone)

从此时起,上述值将被格式化为新时区,而当前显示的时间值不会更改。角度变化检测机制不更新显示的时间值,因为输入值没有改变。

我不想因为性能开销而创建"不纯"管道(考虑到时区更改不是一项频繁的活动)。

作为后备,我可以创建一个以当前时区为参数的管道(或使用现有管道)。它确实有效,但我需要将当前时区值传递给每个组件和模板。

即使在值没有变化的情况下,我也无法找到角度变化检测的方法来相信存在变化。

欢迎提出任何建议。

管道不是组件(显而易见),除了pure标志之外,它们没有自己的更改检测机制。因此,有两种方法可以达到预期的结果:

  1. 使用智能不纯管道,它将跟踪以前的值和以前格式化的结果。Angular的AsyncPipe(实际上是不纯净的,如果有其他方法可以做到这一点,那么我相信它会变得纯净)是这样实现的:

    if (value !== this.value || this.timeZoneChanged) 
    {
    this.value = value;
    this.formattedValue = ... render value ...;
    }
    return this.formattedValue;
    

    您可以在github上浏览AsyncPipe源代码。

  2. 使用自定义组件呈现日期,即自定义ControlValueAccessor

例如,当使用ngx-translate时,切换语言意味着获取新的翻译。正如你在这里看到的,他们使用了一个不纯的管道,正如你所说,这意味着性能问题。

我设想的另一种方法是定义一个可用于整个应用程序的组件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();
}
}

相关内容

  • 没有找到相关文章

最新更新