angular - 在 Angular 2 中动态更改 DatePipe 的语言环境

标签 angular locale angular2-pipe

我正在制作一个 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 有一些错误报告:

有几种解决方法:

解决方法#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/

相关文章:

javascript - Angular 混合应用程序不起作用

javascript - 如何在 Angular js 中将 JSON 嵌套字典转换为 JSON 嵌套数组?

php - 如何在 PHP 中自动设置用户的语言环境?

angular - 如何从 Angular2 中的 prime-ng 轮播中的模板获取索引?

css - 水平滚动上的 Mat-table 背景颜色

Angular2 为什么异步管道

angular - Angular 2中的动态管道

angular - 从 Angular 2 中的组件代码访问模板中异步管道的结果

java - NumberFormat 中的小数分隔符

java - 如何在 Spring WebFlux 中获取语言环境?