3

我目前有内置 angular 4 的应用程序,并想升级到 angular 5。我正在阅读他们如何处理管道中的语言环境,似乎升级不再是一种选择。据我所知,他们希望您 1. 手动导入不同的文化 2. 为每种文化构建单独的应用程序

问题是我为一家支持 351 种不同文化的国际公司工作,我们有 15 个应用程序。如果我想像他们一样继续升级,角度团队真的说我现在必须构建 5265 个不同的应用程序吗?如果我带着那个去我的老板那里,我可能会被赶出房间。

在我们的 angularJs 应用程序中,我们刚刚下载了用户登录时在运行时需要的 $locale 服务,并将提供程序设置为该服务。Angular 没有这样的东西吗?如果不是,我不确定企业级应用程序如何使用这种语言,除非开发人员足够幸运,只需要支持一种文化。

4

3 回答 3

2

在 github 上就这个问题进行交流后,一个已经开始使用的想法是创建一个我在 APP_INITIALIZER 中调用的服务,您可以在下面看到。由于构建时的动态字符串,angular-cli 将为每种文化创建一个块,然后在我提供从服务调用收到的文化字符串后在运行时加载正确的块。

setLocale(localeId: string): Promise<any> {
    this.culture = localeId;
    return new Promise((resolve, reject) => {
      System.import(`@angular/common/locales/${localeId}.js`).then(
        module => {
          registerLocaleData(module.default);
          resolve();
        },
        () => {
          System.import(`@angular/common/locales/${localeId.split('-')[0]}.js`).then(module => {
            registerLocaleData(module.default);
            resolve();
          }, reject);
        }
      );
    });
  }
于 2018-01-05T17:19:34.230 回答
0

我对 angular4 有同样的问题,我想将 AOT 与多种语言一起使用。这就是我所做的:

管道周围的简单包装器以设置语言环境。

@Pipe({name: 'datepipe', pure: true})
export class MyDatePipe extends DatePipe implements PipeTransform {
  constructor(private win: WindowRef) {
    super(win.ln);
  }

  transform(value: any, pattern?: string): string | null {
    return super.transform(value, pattern);
  }
}

地区服务:

function _window(): any {
  // return the global native browser window object
  return window;
}

@Injectable()
export class WindowRef {
  get nativeWindow(): any {
    return _window();
  }

  //default locale
  public ln = 'en';


  constructor() {
    try {
       if (!isNullOrUndefined(this.nativeWindow.navigator.language) && this.nativeWindow.navigator.language !== '') {
        this.ln = this.nativeWindow.navigator.language;
      }
    }finally {}
  }
}

这适用于 angular4 但使用 angular5 我必须在我的 main.ts 中导入支持的语言环境

import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';

registerLocaleData(localeFr);
于 2017-11-07T13:56:02.567 回答
0

我面临同样的问题,并找到了解决方法。

我决定在资产文件夹中发布角度语言环境数据(来自 cldr)。Cldr 数据来自 node_mopdules\@angular\common\locales (您将在 typescript 中导入的内容)。就在引导之前,使用 APP_INITIALIZER,我从给定特定 locale_id 的资产中加载当前文化数据。

诀窍是避免使用import关键字,因为 EC2015 不支持动态导入。为了从 js 文件中获取文化数据,我编写了这个“脏”代码:

import { Injectable, Inject, LOCALE_ID } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class LoaderService {

  constructor(protected httpClient: HttpClient,
              @Inject(LOCALE_ID) protected locale: string) { }

private async loadAngularCulture(locale) {
      let angularLocaleText = await this.httpClient.get(`assets/angular-locales/${locale}.js`).toPromise();

      // extracting the part of the js code before the data, 
      // and i didn't need the plural so i just replace plural by null.
      const startPos = angularLocaleText.indexOf('export default ');
      angularLocaleText = 'return ' + angularLocaleText.substring(startPos + 15).replace('plural', null);

      // The trick is here : to read cldr data, i use a function
      const f = new Function(angularLocaleText);
      const angularLocale = f();

      // console.log(angularLocale);

      // And now, just registrer the object you just created with the function
      registerLocaleData(angularLocale);
  }

并且是我的 mainModule,使用 APP_INITIALIZER :

export function configFactory(intlLoader: SfkIntlLoaderService) {
  return intlLoader.initializer();
}

export function localFunction() {
  // the rule to get you language according. 
  // Here, for demo, i just read it from localstorage
  return localStorage.getItem('LANGUGAGE');
}

@NgModule({
 declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  )
  ],
  providers: [
    LoaderService,
    {
      provide: LOCALE_ID,
      deps: [],
      useFactory: localFunction
    },
    {
      provide: APP_INITIALIZER,
      useFactory: configFactory,
      deps: [LoaderService],
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

希望这会有所帮助!

于 2018-03-02T08:50:30.977 回答