首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >angular-i18n代码翻译的变通方法?

angular-i18n代码翻译的变通方法?
EN

Stack Overflow用户
提问于 2018-01-19 01:47:06
回答 6查看 7.9K关注 0票数 8

我们必须等到Angular 6中的angular-i18n才能支持错误消息等代码的翻译。

对于那些使用angular-i18n (例如,而不是ngx-translate )的用户,您在这段时间内如何处理代码中的翻译?我突然想到,如果没有太多的字符串,那么一个简单的语言服务,通过语言代码和id获取翻译的方法就可以了,但我感兴趣的是更优雅和更“角度”的东西。

我不知道承诺的代码转换支持会是什么样子,但理想情况下,任何临时解决方案在上线时都可以很容易地转换为angular-i18n方式。

人们正在做些什么来处理这个问题呢?有什么想法吗?

EN

回答 6

Stack Overflow用户

发布于 2018-06-21 12:44:44

这个polyfill看起来是现在最好的方法:

https://github.com/ngx-translate/i18n-polyfill

它允许您将想要翻译的任何内容包装在一个i18n()函数中(此API可能会保留在以后的Angular版本中-请参阅此答案底部的注释)。

polyfill主要由Olivier Combe编写,他是负责i18n的Angular团队的成员:

对于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

我让polyfill在Angular 5的JIT和AOT编译中工作(它也可以在Angular 6中工作)。下面是翻译成一种语言需要做的事情(这是一种很好的工作方式--稍后你可以让多种语言工作,我将在下面进一步解释):

app.module.ts

将以下导入添加到您的根Angular模块:

代码语言:javascript
复制
import { TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core';
import { I18n } from '@ngx-translate/i18n-polyfill';

添加以下常量,并在根模块中指定提供程序:

代码语言:javascript
复制
// 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编译完成(这就是为什么您需要引用TRANSLATIONSTRANSLATIONS_FORMAT,而不是仅在构建脚本中指定它们的原因)。

*.ts

在要提供翻译的.ts文件中,添加以下内容:

代码语言:javascript
复制
import { I18n } from '@ngx-translate/i18n-polyfill';

constructor(private i18n: I18n) {
    console.log(i18n("This is a test {{myVar}} !", {myVar: "^_^"}));
}

这表明您甚至可以在要翻译的消息中包含插值。

您可以使用i18n定义(即指定翻译‘源’id,意思,描述),如下所示:

代码语言:javascript
复制
this.i18n({value: 'Some message', id: 'Some message id', meaning: 'Meaning of some message', description: 'Description of some message'})

您仍然需要提取消息,您可以使用ngx-提取器工具来执行此操作。这在您安装polyfill时就包含在内,我已经在下面的npm脚本中添加了一个关于它的用法的示例。另请参阅polyfill page上的自述文件。

多种语言

要支持在多语言之间切换,您需要为您的翻译提供一个工厂提供程序。这里有关于polyfill page的自述文件的详细信息。在你的根模块中需要类似这样的东西(或者对于AOT编译,用一个函数替换localeFactory的返回值,该函数可以检测你的应用程序当前正在运行的AOT编译语言变体):

代码语言:javascript
复制
  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 translate自动执行翻译(您需要一个Google translate API密钥)。为了实现这一点,在进行实际的AOT构建之前,我按照以下顺序进行提取和合并/转换:

代码语言:javascript
复制
"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构建如下所示:

代码语言:javascript
复制
"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编写。在这个阶段,这是一个用于翻译.ts文件中的变量或字符串的“推测性”polyfill。它很可能会被一个内置在Angular中的API所取代,这将是非常相似的,所以以后的升级应该是相当容易管理的。这是来自Github页面的二聚体:

API这个库是一个推测性的polyfill,这意味着它应该取代未来的

。如果API不同,在可能和必要的情况下,会提供迁移工具。

在即将到来的Angular 6的次要版本中,对代码中变量/字符串的翻译的支持已经有了一些讨论。

以下是Olivier Combe (来自今年3月)的一段话,来自Github上的以下讨论:

https://github.com/angular/angular/issues/11405

运行时i18n的第一个PR已经合并到master中,以及一个hello world演示应用程序,我们将使用它来测试功能。它在运行时工作,理论上支持代码翻译,即使还没有为它提供服务。现在它是最小的支持(静态字符串),我们正在努力添加新的功能(我将在下周开始提取,然后使用占位符和变量的动态字符串)。在此之后,我们将提供代码翻译服务。一旦新功能完成,它就会合并到master中,您不必等待新的主要功能。

票数 12
EN

Stack Overflow用户

发布于 2018-09-27 06:51:22

距离我上次回复已经很长时间了,可以简化一下。

如果我们的.html像这样

代码语言:javascript
复制
<!--at first we put all the translation in a hidden div-->
<div *ngIf="!yet" style="display: none">
    <span #t id="message1">Translation app</span>
    <span #t id="message2">Hola Mundo</span>
</div>

在我们的.ts中有一个简单的翻译,一个变量“ViewChildren”和一个变量“ViewChildren”

代码语言:javascript
复制
  yet: boolean = false;
  translation:any={}
  @ViewChildren("t")
  set translations(values: QueryList<any>) {
    //when yet becomes true, values.length=0
    if (values.length) {
      values.forEach(c => {
        this.translation[c.nativeElement.id]=c.nativeElement.innerHTML
      })
      //it's necesary enclosed this.yet=true in a setTime to avoid 
      //the error expresion changes After Exec
      setTimeout(()=>{
        this.yet=true;
      })

    }
  }

然后我们可以写一些类似于

代码语言:javascript
复制
alert(this.translation['message1']);

更新同样的想法:一个组件实现,你就拥有了一个组件

代码语言:javascript
复制
import { Component, QueryList, AfterViewInit, ContentChildren } from '@angular/core';
@Component({
    selector: 'ng-translation',
    template: `
    <div *ngIf="!yet" [style.display]="'none'">
    <ng-content></ng-content>
    </div>
    `
})
export class TranslationComponent implements AfterViewInit {
    @ContentChildren("t") translations: QueryList<any>
    data: any = {}
    yet: boolean = false;

    get(text: string) {
        return this.data[text];
    }
    ngAfterViewInit(): void {
        if (this.translations.length) {
            this.translations.forEach(c => {
                this.data[c.nativeElement.id] = c.nativeElement.innerHTML
            })
            setTimeout(() => {
                this.yet = true;
            })
        }
    }
}

在任何其他组件中

代码语言:javascript
复制
<ng-translation #translation>
  <span #t id="message1">Translation app</span>
  <span #t id="message2">Hola Mundo</span>
</ng-translation>

@ViewChild("translation") translation:TranslationComponent
  click()
  {
    alert(this.translation.get('message1'));
  }

Example in stackblitz

票数 2
EN

Stack Overflow用户

发布于 2020-05-08 15:49:28

查看此博客条目:https://blog.ninja-squad.com/2019/12/10/angular-localize/

简而言之:

有一个$localize可以用来做这件事。

代码语言:javascript
复制
@Component({
  template: '{{ title }}'
})
export class HomeComponent {
   title = $localize`You have 10 users`;
}

不幸的是,这个功能还没有真正完成:

然后,您可以像翻译模板一样翻译消息。但是,现在(v9.0.0),命令行界面不能像模板那样使用xi18n命令提取这些消息。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48327401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档