要从服务设置区域设置,您需要添加LOCALE_ID
供应商与工厂app.module
, 像阿莫尔·博尔的回答 https://stackoverflow.com/questions/44287827/dynamically-change-locale-for-datepipe-in-angular-2/44288739#44288739:
{
provide: LOCALE_ID,
deps: [SettingsService], //some service handling global settings
useFactory: (settingsService) => settingsService.getLanguage() //returns locale string
}
遗憾的是,您无法更改 DatePipe JIT 的语言。 Angular 编译器需要LOCALE_ID
在引导期间。
有一些 Angular 的错误报告:
-
https://github.com/angular/angular/issues/15039 https://github.com/angular/angular/issues/15039(关闭 - 不
解决)
-
https://github.com/angular/angular/issues/16960 https://github.com/angular/angular/issues/16960(关闭
评论中有解决方法)
有几种解决方法:
解决方法#1
重新引导 Angular 模块:
let _platformRef: NgModuleRef<Object>;
if(_platformRef) { _platformRef.destroy(); }
platformBrowserDynamic(providers)
.bootstrapModule(AppModule, {providers})
.then(platformRef => {
_platformRef = platformRef;
})
这对于混合 Angular/AngularJS 不起作用,因为没有任何方法可以使用 UpgradeModule 销毁 AngularJS。
解决方法#2
要覆盖 DatePipe、NumberPipe - 无论您需要什么:
@Pipe({name: 'datepipe', pure: true})
export class MyDatePipe implements PipeTransform {
transform(value: any, pattern?: string): string | null {
// transform value as you like (you can use moment.js and format by locale_id from your custom service)
return DateUtils.format(value);
}
}
解决方法#3
要使用已经通过自定义管道处理本地化的库,例如:
- https://github.com/urish/angular2-moment https://github.com/urish/angular2-moment
- https://github.com/robisim74/angular-l10n https://github.com/robisim74/angular-l10n
解决方法 #4
每一条使用的管道LOCALE_ID
有一个私人领域locale or _locale,因此您可以在语言更改时覆盖这些管道中的该字段,因为存在一个管道实例。
这会起作用,因为 TypeScript 只是句法糖 https://en.wikipedia.org/wiki/Syntactic_sugar对于 JavaScript。在 JavaScript 中没有任何私有字段。
还记得使用以下方法处理应用程序中的更改检测tick()
ApplicationRef 中的方法
@Injectable()
export class DynamicLocaleService {
private i18nPipes: PipeTransform[];
constructor(
datePipe: DatePipe,
currencyPipe: CurrencyPipe,
decimalPipe: DecimalPipe,
percentPipe: PercentPipe,
private applicationRef: ApplicationRef,
) {
this.i18nPipes = [
datePipe,
currencyPipe,
decimalPipe,
percentPipe,
]
}
setLocale(lang: string): void {
this.i18nPipes.forEach(pipe => {
if(pipe.hasOwnProperty("locale")) {
pipe["locale"] = lang;
} else if (pipe.hasOwnProperty("_locale")) {
pipe["_locale"] = lang
}
})
this.applicationRef.tick()
}
}
解决方法#5
更改语言时重新加载应用程序。
window.location.reload()
不幸的是,以上所有都是解决方法。
但还有另一种解决方案。您可以为每种语言提供多个捆绑包,这可能是更好的方法,因为应用程序会更快。但该解决方案并不适用于所有应用程序,也不能回答问题。