Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular国际化集成ngx-translate #102

Open
deepthan opened this issue Sep 10, 2020 · 0 comments
Open

Angular国际化集成ngx-translate #102

deepthan opened this issue Sep 10, 2020 · 0 comments

Comments

@deepthan
Copy link
Owner

国际化集成ngx-translate

用什么做i18n?

https://stackoverflow.com/questions/51087137/angular-6-i18n-vs-ngx-translate

目前有三种方式

使用ngx-translate做法

  • 首先在app.module中引入此插件的module
import {
  HttpClient
} from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';

// i18n
export function createTranslateLoader(http: HttpClient) {
  return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}

@NgModule({
  imports: [
    TranslateModule.forRoot({
       loader: {
         provide: TranslateLoader,
         useFactory: createTranslateLoader,
         deps: [HttpClient]
       }
    })
  ],
})
  • 然后在assets文件夹下建一个i18n文件夹,里面新建两个文件

    • en.json

      {
        "home": "HOME"
      }
      
      
    • zh-CN.json

      {
        "home": "首页"
      }
      
  • 再在app.component.ts中设置默认的语言

import { TranslateService } from '@ngx-translate/core';
@Component({
  selector: 'app-root',
  template: `
    <router-outlet></router-outlet>
    <div>{{ 'home' | translate }}</div>
  `,
})
...


export class AppComponent implements OnInit{

  constructor(public translate: TranslatorService) {
    
    
    translate.setDefaultLang('en');
    translate.use('en');
  }
}

这样div里就可以渲染出来

HOME

选择语言类型渲染不同的语言

  • core文件夹下建i18n/i18n.service.ts并注册,提供获取当前语言、设置语言、获取语言列表,并且是存在localstorage中的。
/**
 * 国际化服务部分
 */ 
import { Injectable, Inject, Injector } from '@angular/core';
import { Router } from '@angular/router';
import { Observable, BehaviorSubject } from 'rxjs';
import { filter } from 'rxjs/operators';

import { en_US, zh_CN, NzI18nService } from 'ng-zorro-antd';
import * as df_en from 'date-fns/locale/en';
import * as df_zh_cn from 'date-fns/locale/zh_cn';
import { TranslateService } from '@ngx-translate/core';
import { AlainI18NService } from '@delon/theme';

@Injectable()
export class I18NService implements AlainI18NService {
  private _default = 'zh-CN';
  private change$ = new BehaviorSubject<string>(null);

  private _langs = [
    { code: 'en', text: 'English' },
    { code: 'zh-CN', text: '中文' },
  ];

  constructor(
    private nzI18nService: NzI18nService,
    private translate: TranslateService,
    private injector: Injector,
  ) {
    const defaultLan = this.storedLang() || translate.getBrowserLang();
    const lans = this._langs.map(item => item.code);
    this._default = lans.includes(defaultLan) ? defaultLan : lans[0];
    translate.addLangs(lans);
    this.setZorro(this._default).setDateFns(this._default);
  }

  setZorro(lang: string): this {
    this.nzI18nService.setLocale(lang === 'en' ? en_US : zh_CN);
    return this;
  }

  setDateFns(lang: string): this {
    (window as any).__locale__ = lang === 'en' ? df_en : df_zh_cn;
    return this;
  }

  get change(): Observable<string> {
    return this.change$.asObservable().pipe(filter(w => w != null));
  }

  use(lang: string): void {
    lang = lang || this.translate.getDefaultLang();
    if (this.currentLang === lang) return;
    this.setZorro(lang).setDateFns(lang);
    this.storeLang(lang);
    this.translate.use(lang).subscribe(() => this.change$.next(lang));
  }

  /** 获取语言列表 */
  getLangs() {
    return this._langs;
  }

  /** 翻译 */
  interpret(key: string) {
    return this.translate.instant(key);
  }

  /** 默认语言 */
  get defaultLang() {
    return this._default;
  }

  /** 当前语言 */
  get currentLang() {
    return (
      this.translate.currentLang ||
      this.translate.getDefaultLang() ||
      this._default
    );
  }

  /** 存选中的语言 **/
  storeLang(lang: string) {
    localStorage.setItem("language", lang);
  }

  /** 取存储的语言 **/
  storedLang() {
    return (
      localStorage.getItem("language")
    );
  }
}

  • 不在app.component.ts中设置默认语言,而是新建一个服务,去设置整个项目的默认配置数据。在core下建startup/startup.service.ts
/**
 * 用于应用启动时
 * 一般用来获取应用所需要的基础数据等
 */
import { Injectable, Injector, Inject } from '@angular/core';
import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { zip } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core';
import { I18NService } from '../i18n/i18n.service';

@Injectable()
export class StartupService {
  constructor(
    private translate: TranslateService,
    private i18n: I18NService,
    private injector: Injector,
    private httpClient: HttpClient,
  ) {}

  load(): Promise<any> {
    // 只支持用promise实现
    // https://github.com/angular/angular/issues/15088
    return new Promise((resolve, reject) => {
      zip(
        this.httpClient.get(`assets/i18n/${this.i18n.defaultLang}.json`),
      )
        .pipe(
          // 接收其他拦截器后产生的异常消息
          catchError(([langData]) => {
            resolve(null);
            return [langData];
          }),
        )
        .subscribe(
          ([langData]) => {
            // 设置默认语言
            this.translate.setTranslation(this.i18n.defaultLang, langData);
            this.translate.setDefaultLang(this.i18n.defaultLang);
          },
          () => {},
          () => {
            resolve(null);
          },
        );
    });
  }
}

  • 最后在一个组件里面选择语言
<nz-select style="width: 120px;" [(ngModel)]="selectedValue" nzAllowClear nzPlaceHolder="Choose" (ngModelChange)="changeLang()">
  <nz-option nzValue="en" nzLabel="en"></nz-option>
  <nz-option nzValue="zh-CN" nzLabel="zh-CN"></nz-option>
</nz-select>
import { Component, OnInit } from '@angular/core';

import { I18NService } from '@core/i18n/i18n.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent {

  constructor(
    private i18NService : I18NService
  ) { }

  selectedValue : ""
  changeLang(){
    this.i18NService.use(this.selectedValue)
  }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant