问题
I have a simple generic component in Angular
which receives a list of strings and creates a radio group for these strings:
@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;
}
I need the radio group labels internationalized.
The official i18n
documentation of Angular
talks only about static HTML.
Is there any way to internationalize dynamic components (like *ngFor
entries) with i18n
template translation?
I'm aware of ngx-translate
way, I'm interested particularly in i18n
way.
回答1:
I was looking for the very same thing and also for an option to do dynamic translation without ngx-translate. ocombe seems to be the one responible for i18n at Angular. In this GitHub issue #16477 he posted some kind of roadmap for i18n in Angular.
▢ Use translation strings outside of a template - #11405 [blocked by runtime i18n]
As you can see this feature is not implemented in Angular yet but it's planned. The issue that is blocking this feature luckily is in progress:
▢ Runtime i18n (one bundle for all locales with AOT) - [working on it]
I don't remember where I read it but I think ocombe wrote, they want to implement this feature still in Angular 5 so it might be available before spring 2018 (the Angular roadmap says Angular 6 will be published in spring 2018)
Date: March/April 2018; Stable Release: 6.0.0
ocombe just posted this today:
I'm not the one working on this feature, and it's the holidays break, I'll let you know as soon as I know more
So all that remains is to use ngx-translate if you cannot wait, or you could subscribe to these GitHub issues #11405 & #16477 and get updated until they make this feature available. Hopefully early 2018 :)
PS: as far as I understood they also want to implement dynamic translation, but I think it wont be available before Angular 6.
UPDATE:
Now it's official: Runtime i18n wont be before Angular 6 (see: 11405#issuecomment-358449205)
EDIT:
I found a dirty hack to do that. you can create hidden div tags for your translations and save them via ViewChildren in a map for further use. You could even subscribe to the elements to update them.
@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);
}
回答2:
I am using @ngx-translate. What I did is, I declare the content that I want to translate in both language files, in my case es.json
, and 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"
}
In the component that I want to translate, in my case the contents.component.ts
, I: i) declare an array of contents; ii) inject the translate Service; iii) set it; iv) loop a for in which you construct an object that looks like this,
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() {
}
}
Finally, in my contents.component.html looks like this
<ul>
<li *ngFor= "let content of contents" >
{{ content.content | translate }}
</li>
</ul>
You can improve this code and make it better :) I Hope could be useful.
来源:https://stackoverflow.com/questions/41824611/angular-internationalization-i18n-and-ngfor