我正在制作一个 Angular 项目,用户可以在其中切换语言。是否可以使语言环境动态化?
我看到您可以将它添加到 NgModule 中,但我猜当我把它放在那里时它不是动态的?或者我可以通过服务或其他方式以某种方式更改它吗?
最佳答案
要从服务中设置语言环境,您需要将带有工厂的 LOCALE_ID
提供程序添加到 app.module
,就像@AmolBhor 中的回答
{
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/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
要使用已经通过自定义管道处理本地化的库,例如:
解决方法#4
每个使用 LOCALE_ID
的管道都有私有(private)字段 locale 或 _locale,所以您可以在语言更改时覆盖该管道的这个字段,因为有一个管道实例。
这会起作用,因为 TypeScript 只是 JavaScript 的语法糖。在 JavaScript 中没有私有(private)字段。
还记得在 ApplicationRef 中使用 tick()
方法处理应用程序中的更改检测。
@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()
不幸的是,以上所有都是解决方法。
但还有另一种解决方案 - 您可以为每种语言设置多个 bundle ,这可能是更好的方法,因为应用程序会更快。但是这个解决方案并不适用于所有应用程序,也没有回答问题。
关于angular - 在 Angular 2 中动态更改 DatePipe 的语言环境,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44287827/