typescript Angular 2 i18n 动态/即时翻译

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42024207/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:14:10  来源:igfitidea点击:

Angular 2 i18n dynamic/instant translation

javascriptangulartypescriptinternationalization

提问by Andre Debuisne

I've followed the angular.io cookbook for internationalization (https://angular.io/docs/ts/latest/cookbook/i18n.html#!#angular-i18n). Everything works fine, and if I change my locale in the index.html file:

我遵循了 angular.io 国际化食谱(https://angular.io/docs/ts/latest/cookbook/i18n.html#!#angular-i18n)。一切正常,如果我在 index.html 文件中更改我的语言环境:

document.locale = 'en';

But I wish to change this dynamically, as we used to do in AngularJS. I have found several solutions, such as this:

但我希望动态地改变这一点,就像我们过去在 AngularJS 中所做的那样。我找到了几种解决方案,例如:

//mycomponent.component.ts
changeLang(){
localStorage.setItem('localeId', "es");
location.reload(true);

} //I hardcoded the locale, but you get the idea

Is there a way to translate the document on the go? Because this solution is not practical, and has a long reload time. Thank you for your help!

有没有办法随时随地翻译文档?因为这个方案不实用,重装时间长。谢谢您的帮助!

回答by JeB

In short it is not possible to change the locale without reloading the app as the translation work is done by Angularcompiler.

简而言之,在不重新加载应用程序的情况下无法更改区域设置,因为翻译工作是由Angular编译器完成的。



As of today you have two optionswhen using official Angular i18n:

截至今天,您在使用官方时有两种选择Angular i18n

Use AOT compiler

使用AOT 编译器

In this case a separate bundle will be created for every locale and you'll have to swap the whole application, i.e. reload it.

在这种情况下,将为每个语言环境创建一个单独的包,您必须交换整个应用程序,即重新加载它。

When you internationalize with the AOT compiler, you must pre-build a separate application package for each language and serve the appropriate package based on either server-side language detection or url parameters.

当您使用 AOT 编译器进行国际化时,您必须为每种语言预先构建一个单独的应用程序包,并根据服务器端语言检测或 url 参数提供适当的包。

Use JIT compiler

使用JIT 编译器

This approach is less performant but you'll not necessarily need a bundle per language.
In this case you load your translation file with webpackand provide it to Angularcompiler during bootstrap.

这种方法的性能较低,但您不一定需要每种语言一个包。
在这种情况下,您加载翻译文件webpackAngular在引导期间将其提供给编译器。

The JIT compiler compiles the app in the browser as the app loads. Translation with the JIT compiler is a dynamic process of:

  • Importing the appropriate language translation file as a string constant.
  • Creating corresponding translation providers for the JIT compiler.
  • Bootstrapping the app with those providers.

JIT 编译器在应用加载时在浏览器中编译应用。使用 JIT 编译器进行翻译是一个动态过程:

  • 将适当的语言翻译文件作为字符串常量导入。
  • 为 JIT 编译器创建相应的翻译提供程序。
  • 使用这些提供程序引导应用程序。

Although in the official documentation they only have examples with useValueproviders, I'm pretty sure you can use useFactoryto provide TRANSLATIONSand LOCALE_IDbased on your configuration.
You'll still have to re-bootstrap your app upon language change, which, in turn, means reloading, but hey, the user have this bundle cached in the browser, so the reload should be pretty fast.

尽管在官方文档中他们只有useValue提供程序的示例,但我很确定您可以根据您的配置useFactory提供TRANSLATIONS和使用LOCALE_ID
您仍然需要在语言更改时重新引导您的应用程序,这反过来意味着重新加载,但是嘿,用户将此包缓存在浏览器中,因此重新加载应该非常快。



Anyways, as of now, if you want to get really dynamic translations I'd suggest you to use ngx-translate.
Besides translatepipe and service they have this nice speculative polyfillthat might save you some headache when code translations will be supported officially by Angular i18n.

无论如何,到目前为止,如果您想获得真正动态的翻译,我建议您使用ngx-translate
除了translate管道和服务之外,他们还有这个很好的推测性 polyfill,当Angular i18n.

回答by Chris Halcrow

You can certainly do this if you're using JIT compilation. You'll need a factory provider for your translations. Add something like this to your root module:

如果您使用 JIT 编译,您当然可以这样做。您需要一家工厂供应商来进行翻译。将这样的内容添加到您的根模块中:

  export function localeFactory(): string {
    return (window.clientInformation && window.clientInformation.language) || window.navigator.language;
  }

  providers:
  [
    {
      provide: TRANSLATIONS,
      useFactory: (locale) => {
        locale = locale || 'en'; // default to english if no locale provided
        return require(`raw-loader!../locale/messages.${locale}.xlf`);
      },
      deps: [LOCALE_ID]
    },
    {
      provide: LOCALE_ID,
      useFactory: localeFactory
    },
    {provide: TRANSLATIONS_FORMAT, useValue: 'xlf'},

回答by Alex Beugnet

You can check that out, for me it works flawlessly and has great performance (instant translation with no loading time nor reload) :

你可以检查一下,对我来说它完美无缺并且具有出色的性能(即时翻译,无需加载时间或重新加载):

https://github.com/ocombe/ng2-translate

https://github.com/ocombe/ng2-translate

You can then use a local storage or anything with that to set the language :

然后,您可以使用本地存储或任何带有它的东西来设置语言:

translateService.use(window.localStorage.getItem('language'));

translateService.use(window.localStorage.getItem('language'));

You can set your translations in a single file, and you can order the translations in JSON format : (I encapsulate one object per component)

您可以在单个文件中设置您的翻译,并且您可以以 JSON 格式对翻译进行排序:(我为每个组件封装了一个对象)

"PASSWORD_CONFIRM": {
    "TITLE": "Merci !",
    "DESCRIPTION": "Votre nouveau mot de passe a bien été enregistré. Vous pouvez désormais accéder à la plateforme !",
    "BUTTON": "Entrer sur la plateforme"
  },
  ...

and then you can set your text in your HTML as follow :

然后你可以在你的 HTML 中设置你的文本如下:

  <div class="title">{{'PASSWORD_CONFIRM.TITLE' | translate}}</div>
  <div class="description">
      {{'PASSWORD_CONFIRM.DESCRIPTION' | translate}}
  </div>