Angular internationalization (i18n) and *ngFor

后端 未结 3 1950
清歌不尽
清歌不尽 2021-01-08 00:11

I have a simple generic component in Angular which receives a list of strings and creates a radio group for these strings:

@Component({
  sele         


        
相关标签:
3条回答
  • 2021-01-08 00:30

    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);
    }
    
    0 讨论(0)
  • 2021-01-08 00:45

    In Angular 9 you can use global $localize function like this:

    $localize`String to translate`
    

    Great article on this: https://blog.ninja-squad.com/2019/12/10/angular-localize/

    0 讨论(0)
  • 2021-01-08 00:54

    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.

    0 讨论(0)
提交回复
热议问题