Angular 国际化 (i18n) 和 *ngFor
Posted
技术标签:
【中文标题】Angular 国际化 (i18n) 和 *ngFor【英文标题】:Angular internationalization (i18n) and *ngFor 【发布时间】:2017-06-09 00:58:44 【问题描述】:我在Angular
中有一个简单的通用组件,它接收字符串列表并为这些字符串创建一个单选组:
@Component(
selector: 'radio-group',
templateUrl:
`<div *ngFor="let item of items">
<label for="input_item">item</label>
<input type="radio" id="input_item" value="item" [formControl]="radioControl">
</div>`,
styleUrls: ['./radio-group.component.scss']
)
export class RadioGroupComponent
@Input()
items: string[];
@Input()
radioControl: FormControl;
我需要国际化电台组标签。Angular
的官方i18n
documentation 只谈论静态html。
有没有办法通过i18n
模板翻译来国际化动态组件(如*ngFor
条目)?
我知道ngx-translate
方式,我对i18n
方式特别感兴趣。
【问题讨论】:
最好在 .ts 中执行此操作,但这还不能作为 angular2 i18n 的一部分。类似请求github.com/angular/angular/issues/12008 和github.com/angular/angular/issues/11405 【参考方案1】:我一直在寻找同样的东西,同时也在寻找一个不使用 ngx-translate 进行动态翻译的选项。 ocombe 似乎是 Angular 中 i18n 的负责人。在这个 GitHub 问题 #16477 中,他发布了一些关于 Angular 中 i18n 的路线图。
▢ 在模板之外使用翻译字符串 - #11405 [被运行时 i18n 阻止]
如您所见,该功能尚未在 Angular 中实现,但已在计划中。幸运的是,阻止此功能的问题正在进行中:
▢ 运行时 i18n(一个适用于所有带 AOT 的语言环境的捆绑包)- [正在开发中]
我不记得我在哪里读到的,但我认为 ocombe 写道,他们希望仍在 Angular 5 中实现此功能,因此它可能在 2018 年春季之前可用(Angular roadmap 表示 Angular 6 将于 2018 年春季发布)
日期:2018 年 3 月/4 月;稳定版:6.0.0
ocombe 今天刚刚发布了this:
我不是开发此功能的人,现在是假期,我会在知道更多信息后立即通知您
所以剩下的就是使用 ngx-translate 如果您迫不及待,或者您可以订阅这些 GitHub 问题 #11405 和 #16477 并在他们提供此功能之前进行更新。希望 2018 年初 :)
PS:据我了解,他们也想实现动态翻译,但我认为在 Angular 6 之前它不会可用。
更新:
现在正式发布:运行时 i18n 不会出现在 Angular 6 之前(请参阅:11405#issuecomment-358449205)
编辑: 我发现了一个肮脏的黑客来做到这一点。您可以为您的翻译创建隐藏的 div 标签,并通过 ViewChildren 将它们保存在地图中以供进一步使用。您甚至可以订阅元素来更新它们。
@ViewChildren('test') myChildren; // the class needs to implement AfterViewInit
myMap = new Map();
ngAfterViewInit()
this.myChildren.forEach(value => this.myMap.set(value.nativeElement.getAttribute('name'), value.nativeElement.innerHTML));
console.log(this.myMap);
【讨论】:
您可以关注新 Ivy 渲染器的进度,这将使 i18n 运行时可用:github.com/angular/angular/issues/21706 看起来 i18n 具有更多功能,现在又近了一步 :) github.com/angular/angular/issues/11405#issuecomment-375769568【参考方案2】:我正在使用@ngx-translate。我所做的是,我声明了我想要在两种语言文件中翻译的内容,在我的情况下为es.json
和en.json
。
es.json:
"CONTENTS":
"CONT_1": "TEXTO_1",
"CONT_2": "TEXTO_1",
"CONT_3": "TEXTO_1",
"CONT_4": "TEXTO_1",
"CONT_5": "TEXTO_1",
"CONT_6": "TEXTO_1",
"CONT_7": "TEXTO_1",
"CONT_8": "TEXTO_1",
"CONT_9": "TEXTO_1",
"CONT_10": "TEXTO_1",
"CONT_11": "TEXTO_1"
en.json:
"CONTENTS":
"CONT_1": "TEXT_1",
"CONT_2": "TEXT_1",
"CONT_3": "TEXT_1",
"CONT_4": "TEXT_1",
"CONT_5": "TEXT_1",
"CONT_6": "TEXT_1",
"CONT_7": "TEXT_1",
"CONT_8": "TEXT_1",
"CONT_9": "TEXT_1",
"CONT_10": "TEXT_1",
"CONT_11": "TEXT_1"
在我要翻译的组件中,在我的例子中是contents.component.ts
,我:i) 声明一个内容数组; ii) 注入翻译服务; iii) 设置它; iv) 循环一个 for 你在其中构造一个看起来像这样的对象,
import Component, OnInit from '@angular/core';
import TranslateService from '@ngx-translate/core';
@Component(
selector: 'app-contents',
templateUrl: './contents.component.html',
styleUrls: ['./contents.component.css']
)
export class ContentsComponent implements OnInit
// i) Declare an array
public contents = [];
// inject the translateService
constructor(public translateService: TranslateService)
// iii) set it
translateService.addLangs(['es', 'en']);
translateService.setDefaultLang('es');
const browserLang = translateService.getBrowserLang();
translateService.use(browserLang.match(/es|en/) ? browserLang : 'es');
// loop for build a content object and push to the array
for (let index = 1; index <= 11; index++)
const contentObj =
id: index,
content: 'CONTENTS.CONT_' + index.toString()
;
this.contents.push(contentObj);
ngOnInit()
最后,在我的contents.component.html中是这样的
<ul>
<li *ngFor= "let content of contents" >
content.content | translate
</li>
</ul>
您可以改进此代码并使其变得更好:) 我希望有用。
【讨论】:
【参考方案3】:在 Angular 9 中,您可以像这样使用全局 $localize
函数:
$localize`String to translate`
关于此的精彩文章:https://blog.ninja-squad.com/2019/12/10/angular-localize/
【讨论】:
以上是关于Angular 国际化 (i18n) 和 *ngFor的主要内容,如果未能解决你的问题,请参考以下文章
Angular Universal 与 i18n(服务器端渲染)
深究AngularJS——angular-translate详解