Angular Material Datepicker如何在运行时切换对应语言的DateAdapter
解决方案
你之前的代码不生效是因为手动创建的独立注入器和项目全局注入器没有关联,修改的实例不会作用到已渲染的Datepicker组件上。按以下步骤修改即可实现不刷新切换适配器:
1. 注入依赖
在你处理语言切换的组件/公共服务中,注入全局的日期适配器和日期格式实例:
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core'; import { ChangeDetectorRef, Inject } from '@angular/core'; import { MaterialPersianDateAdapter, PERSIAN_DATE_FORMATS } from './material.persian-date.adapter'; import { GregorianDateAdapter } from './gregorian-date-adapter'; import { MAT_MOMENT_DATE_FORMATS } from './moment-date-format'; constructor( private dateAdapter: DateAdapter<any>, @Inject(MAT_DATE_FORMATS) private dateFormats: any, @Inject(MAT_DATE_LOCALE) private locale: string, // 如果适配器构造需要 locale 参数就注入 private cdr: ChangeDetectorRef ) {}
2. 编写切换逻辑
在语言切换的触发方法中,替换适配器实例和日期格式,同时触发变更通知:
// lang为切换后的语言标识,比如 'fa' / 'en' switchDateAdapter(lang: string) { localStorage.setItem('language', lang); // 替换适配器和格式,构造函数需要传 locale 就传入注入的 locale 即可 if (lang === 'fa') { this.dateAdapter = new MaterialPersianDateAdapter(this.locale); Object.assign(this.dateFormats, PERSIAN_DATE_FORMATS); } else { this.dateAdapter = new GregorianDateAdapter(this.locale); Object.assign(this.dateFormats, MAT_MOMENT_DATE_FORMATS); } // 触发适配器变更事件,通知所有Datepicker更新 this.dateAdapter.setLocale(lang); // 触发当前组件视图更新,如果是服务中调用可以省略,在对应组件手动标记变更即可 this.cdr.markForCheck(); // 可选:如果有绑定了日期的响应式表单,手动触发值更新 // this.dateFormControl.setValue(this.dateFormControl.value); }
注意事项
- 如果切换时Datepicker弹窗处于打开状态,需要先关闭再打开才会渲染新格式
- 原有模块的Provider配置不需要修改,初始化逻辑保持不变即可
内容的提问来源于stack exchange,提问作者Mr Coder
相关产品推荐
相关产品推荐

