Car*_*rbo 7 angular-i18n angular angular5
我们必须等到Angular 6 for angular-i18n才能支持错误消息代码的翻译等.
对于那些使用angular-i18n(例如,而不是ngx-translate)的人,你在做什么同时处理代码中的翻译?在我看来,如果没有很多字符串,那么一个简单的语言服务,通过语言代码和id来获得翻译的方法就可以了,但我对更优雅和"有棱角"的东西感兴趣.
我不知道承诺的代码翻译支持会是什么样子,但任何临时解决方案在上线时都可以很容易地转换为angular-i18n方式.
有什么人在处理这个问题?有任何想法吗?
Chr*_*row 10
这种polyfill似乎是现在最好的方式:
https://github.com/ngx-translate/i18n-polyfill
它允许您在i18n()函数中包装您想要翻译的任何内容(此API可能会在Angular的未来版本中保留 - 请参阅本答案底部的注释).
polyfill主要由负责i18n的Angular团队成员Olivier Combe编写:
对于Angular 5,安装时需要0.2.0版本:
npm install @ngx-translate/i18n-polyfill@0.2.0 --save
对于Angular 6,获取最新版本 - 目前为1.0.0:
npm install @ngx-translate/i18n-polyfill@1.0.0 --save
对于Angular 5,我将polyfill 用于JIT和AOT编译(它也适用于Angular 6).以下是翻译成单一语言所需要做的事情(这是一种很好的工作方式 - 您可以在以后使用多种语言,我会进一步解释):
将以下导入添加到根Angular模块:
import { TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core';
import { I18n } from '@ngx-translate/i18n-polyfill';
添加以下常量,并在根模块中指定提供程序:
// add this after import + export statements
// you need to specify the location for your translations file
// this is the translations file that will be used for translations in .ts files
const translations = require(`raw-loader!../locale/messages.fr.xlf`);
@NgModule({ ....
  providers:
  [
    I18n,
    {provide: TRANSLATIONS, useValue: translations},
    {provide: TRANSLATIONS_FORMAT, useValue: 'xlf'},
    ...
关于使用AOT编译的注意事项:如果您正在使用AOT编译来翻译模板,那么.ts文件中的消息翻译仍将在运行时使用JIT编译完成(这就是您需要引用的原因
TRANSLATIONS,TRANSLATIONS_FORMAT而不是仅仅在构建脚本).
在要提供翻译的.ts文件中,添加以下内容:
import { I18n } from '@ngx-translate/i18n-polyfill';
constructor(private i18n: I18n) {
    console.log(i18n("This is a test {{myVar}} !", {myVar: "^_^"}));
}
这表明您甚至可以在要翻译的消息中包含插值.
您可以使用i18n定义(即使用指定翻译'source'id,含义,描述),如下所示:
this.i18n({value: 'Some message', id: 'Some message id', meaning: 'Meaning of some message', description: 'Description of some message'})
您仍然需要提取消息,并且可以使用ngx-extractor工具执行此操作.这是在安装polyfill时包含的,我在npm脚本中添加了一个下面的示例.另请参阅polyfill页面上的自述文件.
要支持在多种语言之间切换,您需要为翻译提供工厂提供程序.有关填充页面的自述文件的详细信息.你需要在你的根模块中使用这样的东西(或者对于AOT编译,localeFactory用一个函数替换返回值,该函数检测你的app当前正在运行的AOT编译语言变体):
  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
    },
所有这些都与xliffmerge兼容,xliffmerge是一个很好的工具,可以自动合并您添加的任何新翻译,而不会覆盖现有翻译.Xliffmerge还可以使用Google翻译自动执行翻译(您需要Google翻译API密钥).为了实现这一点,在进行实际的AOT构建之前,我按以下顺序进行提取和合并/转换:
"extract-i18n-template-messages": "ng xi18n --outputPath=src/locale --i18n-format=xlf",
"extract-i18n-ts-messages": "ngx-extractor --input=\"src/**/*.ts\" --format=xlf --out-file=src/locale/messages.xlf",
"generate-new-translations": "xliffmerge --profile xliffmerge.json en fr es de zh"
针对特定语言版本的网站的AOT构建如下所示:
"build:fr": "ng build --aot --output-path=dist/fr --base-href /fr/ --i18nFile=src/locale/messages.fr.xlf --i18nFormat=xlf --locale=fr",
这主要由负责i18n的Angular团队成员Olivier Combe撰写.在这个阶段,这是一个'推测'polyfill,用于翻译.ts文件中的变量或字符串.它可能会被Angular中内置的API所取代,这将非常相似,因此以后升级应该是合理可管理的.这是来自Github页面的备忘录:
这个库是一个推测性的polyfill,它意味着它应该替换将来出现的API.如果API不同,如果可能且必要,将提供迁移工具.
关于支持即将出现的Angular 6的次要版本,代码中的变量/字符串的翻译.
以下是Olivier Combe(今年3月起)的引用,来自以下关于Github的讨论:
https://github.com/angular/angular/issues/11405
运行时i18n的第一个PR已合并为master,以及我们将用于测试功能的hello world演示应用程序.它在运行时工作,并支持理论上的代码转换,即使它还没有服务.目前它是非常小的支持(静态字符串),我们正在努力添加新功能(我将在下周进行提取工作,然后使用占位符和变量进行动态字符串).之后我们将为代码翻译提供服务.一旦新功能完成,它就会合并到master中,您不必等待新的专业版.
我有一个“奇怪”的解决方法我们可以有两个组件
应用程序文本.component.ts
import { Component} from '@angular/core';
@Component({
  selector: 'text',
  template:`<ng-content></ng-content>`
})
export class AppTextComponent{}
和 app-translation.component.ts
import { Component, QueryList, ElementRef, ContentChildren } from '@angular/core';
import { AppTextComponent } from './app-text.component';
@Component({
  selector: 'app-translation',
  template: `<ng-content></ng-content>`
})
export class AppTranslationComponent{
  @ContentChildren(AppTextComponent, { read: ElementRef }) divs: QueryList<ElementRef>;
  constructor() { }
  translate(id: string): string {
    let nativeElement: any = this.divs.find(e => e.nativeElement.id == id);
    return nativeElement ? nativeElement.nativeElement.innerText : "";
  }
}
然后,在一个组件中我们可以有一些类似的东西
  <app-translation #translations style="visibility:collapsed">
    <text id="message1">Translation app</text>
    <text id="message2">Hola Mundo</text>
  </app-translation>
//In your code you can use a ViewChild and the function "traslate"
  @ViewChild('translations') t;
  alert(this.t.translate("message1"));
| 归档时间: | 
 | 
| 查看次数: | 4281 次 | 
| 最近记录: |