当前位置: 首页 > 工具软件 > NG-Alain > 使用案例 >

基于ng-alain做国际化

龙令雪
2023-12-01

1.下载需要下载的包

在package.json文件的dependencies下加入
“@ngx-translate/core”: “^13.0.0”,
“@ngx-translate/http-loader”: “^6.0.0”,
在终端输入npm install 下载这两个模块

2.加载支持i18n模块

2-1. 修改app.module.ts

加入加载i18n语言文件的代码:

import { ALAIN_I18N_TOKEN } from '@delon/theme';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { I18NService } from './core/i18n/i18n.service';

// 加载i18n语言文件
export function I18nHttpLoaderFactory(http: HttpClient): TranslateHttpLoader {
  return new TranslateHttpLoader(http, `/assets/i18n/`, '.json');
}
const I18NSERVICE_MODULES = [
  TranslateModule.forRoot({
    loader: {
      provide: TranslateLoader,
      useFactory: I18nHttpLoaderFactory,
      deps: [HttpClient],
    },
  }),
];

const I18NSERVICE_PROVIDES = [{ provide: ALAIN_I18N_TOKEN, useClass: I18NService, multi: false }];

在@NgModule修改providers

  providers: [...LANG_PROVIDES, ...INTERCEPTOR_PROVIDES, ...I18NSERVICE_PROVIDES, ...APPINIT_PROVIDES],

在src/app/i18n/下创建i18n.service.ts

import { Platform } from '@angular/cdk/platform';
import { registerLocaleData } from '@angular/common';
import ngEn from '@angular/common/locales/en';
import ngZh from '@angular/common/locales/zh';
import ngJaJp from '@angular/common/locales/ja';
import { Injectable } from '@angular/core';
import {
  AlainI18NService,
  DelonLocaleService,
  en_US as delonEnUS,
  SettingsService,
  zh_CN as delonZhCn,
  ja_JP as delonJaJp,
} from '@delon/theme';
import { TranslateService } from '@ngx-translate/core';
import { enUS as dfEn, zhCN as dfZhCn, ja as dfJaJp } from 'date-fns/locale';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { en_US as zorroEnUS, NzI18nService, zh_CN as zorroZhCN, ja_JP as zorroJaJp } from 'ng-zorro-antd/i18n';
import { BehaviorSubject, Observable } from 'rxjs';
import { filter } from 'rxjs/operators';

interface LangData {
  abbr: string;
  text: string;
  ng: NzSafeAny;
  zorro: NzSafeAny;
  date: NzSafeAny;
  delon: NzSafeAny;
}

const DEFAULT = 'zh-CN';
const LANGS: { [key: string]: LangData } = {
  'zh-CN': {
    text: '简体中文',
    ng: ngZh,
    zorro: zorroZhCN,
    date: dfZhCn,
    delon: delonZhCn,
    abbr: '',
  },
  'ja-JP': {
    text: '日本語',
    ng: ngJaJp,
    zorro: zorroJaJp,
    date: dfJaJp,
    delon: delonJaJp,
    abbr: 'Ja',
  },
  'en-US': {
    text: 'English',
    ng: ngEn,
    zorro: zorroEnUS,
    date: dfEn,
    delon: delonEnUS,
    abbr: '',
  },
};

@Injectable({ providedIn: 'root' })
export class I18NService implements AlainI18NService {
  private _default = DEFAULT;
  private change$ = new BehaviorSubject<string | null>(null);

  private _langs = Object.keys(LANGS).map((code) => {
    const item = LANGS[code];
    return { code, text: item.text, abbr: item.abbr };
  });

  constructor(
    private settings: SettingsService,
    private nzI18nService: NzI18nService,
    private delonLocaleService: DelonLocaleService,
    private translate: TranslateService,
    private platform: Platform,
  ) {
    // `@ngx-translate/core` 预先知道支持哪些语言
    const lans = this._langs.map((item) => item.code);
    translate.addLangs(lans);

    const defaultLan = this.getDefaultLang();
    if (lans.includes(defaultLan)) {
      this._default = defaultLan;
    }

    this.updateLangData(this._default);
  }

  private getDefaultLang(): string {
    if (!this.platform.isBrowser) {
      return DEFAULT;
    }
    if (this.settings.layout.lang) {
      return this.settings.layout.lang;
    }
    return (navigator.languages ? navigator.languages[0] : null) || navigator.language;
  }

  private updateLangData(lang: string): void {
    const item = LANGS[lang];
    registerLocaleData(item.ng);
    this.nzI18nService.setLocale(item.zorro);
    this.nzI18nService.setDateLocale(item.date);
    this.delonLocaleService.setLocale(item.delon);
  }

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

  use(lang: string): void {
    lang = lang || this.translate.getDefaultLang();
    if (this.currentLang === lang) {
      return;
    }
    this.updateLangData(lang);
    this.translate.use(lang).subscribe(() => this.change$.next(lang));
  }
  /** 获取语言列表 */
  getLangs(): Array<{ code: string; text: string; abbr: string }> {
    return this._langs;
  }
  /** 翻译 */
  fanyi(key: string, interpolateParams?: {}): any {
    return this.translate.instant(key, interpolateParams);
  }
  /** 默认语言 */
  get defaultLang(): string {
    return this._default;
  }
  /** 当前语言 */
  get currentLang(): string {
    return this.translate.currentLang || this.translate.getDefaultLang() || this._default;
  }
}

在StartupService.ts中加载特定语言的语言包

import { I18NService } from '../i18n/i18n.service';
import { TranslateService } from '@ngx-translate/core';
import { HttpClient } from '@angular/common/http';
import { MenuService, SettingsService, TitleService, ALAIN_I18N_TOKEN } from '@delon/theme';
@Injectable()
export class StartupService {
  constructor(
    ...
    private translate: TranslateService,
    @Inject(ALAIN_I18N_TOKEN) private i18n: I18NService,
    private httpClient: HttpClient,
    private injector: Injector
  ) {
    iconSrv.addIcon(...ICONS_AUTO, ...ICONS);
  }
load(): Promise<any> {
    // only works with promises
    // https://github.com/angular/angular/issues/15088
    return new Promise((resolve,reject ) => {
      // 按你自己的业务需要进行加载配置
     this.httpClient.get(`./assets/i18n/${this.i18n.defaultLang}.json`)
     .pipe(data => data)
     .subscribe(data => {  
       this.translate.setTranslation(this.i18n.defaultLang,data);//主要代码
       this.translate.setDefaultLang(this.i18n.defaultLang);//主要代码
        this.menuService.add([ 
          {
            text: 'main',
            group: false,
            translate: 'menu.main',
            children: [
              {
                text: '特性值配置',
                icon: { type: 'icon', value: 'mail' },
                link: '/queryAttribute',
                i18n: 'menu.AttributeSet',
                group: true
                
              }, {
                text: `视图显示`,
                icon: { type: 'icon', value: 'bar-chart' },
                link: '/queryView',
                i18n: "menu.ViewSet",
                group: true
              } ]            
          }
          ]);          
     });     
      resolve({});
 
  });
  }

使用和修改默认语言

在src/app/layout/default/header/components/创建(具体目录自己定)i18n.component.ts

import { DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, Component, Inject, Input } from '@angular/core';
import { ALAIN_I18N_TOKEN, SettingsService } from '@delon/theme';
import { BooleanInput, InputBoolean } from '@delon/util';
import { I18NService } from 'src/app/core/i18n/i18n.service';



@Component({
  selector: 'header-i18n',
  template: `
    <div *ngIf="showLangText" nz-dropdown [nzDropdownMenu]="langMenu" nzPlacement="bottomRight">
      <i nz-icon nzType="global"></i>
      {{ 'menu.lang' | translate }} 
      <i nz-icon nzType="down"></i>
    </div>
    <i *ngIf="!showLangText" nz-dropdown [nzDropdownMenu]="langMenu" nzPlacement="bottomRight" nz-icon nzType="global"></i>
    <nz-dropdown-menu #langMenu="nzDropdownMenu">
      <ul nz-menu>
        <li nz-menu-item *ngFor="let item of langs" [nzSelected]="item.code === curLangCode" (click)="change(item.code)">
          <span role="img" [attr.aria-label]="item.text" class="pr-xs">{{ item.abbr }}</span>
          {{ item.text }}
        </li>
      </ul>
    </nz-dropdown-menu>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HeaderI18nComponent {
  static ngAcceptInputType_showLangText: BooleanInput;
  /** Whether to display language text */
  @Input() @InputBoolean() showLangText = true;

  get langs(): Array<{ code: string; text: string; abbr: string }> {
    return this.i18n.getLangs();
  }

  get curLangCode(): string {
    return this.settings.layout.lang;
  }

  constructor(private settings: SettingsService, @Inject(ALAIN_I18N_TOKEN) private i18n: I18NService, @Inject(DOCUMENT) private doc: any) {}

  change(lang: string): void {
    const spinEl = this.doc.createElement('div');
    spinEl.setAttribute('class', `page-loading ant-spin ant-spin-lg ant-spin-spinning`);
    spinEl.innerHTML = `<span class="ant-spin-dot ant-spin-dot-spin"><i></i><i></i><i></i><i></i></span>`;
    this.doc.body.appendChild(spinEl);

    this.i18n.use(lang);
    this.settings.setLayout('lang', lang);
    setTimeout(() => this.doc.location.reload());
  }
}

在header.component.html中引用HeaderI18nComponent

<div nz-menu-item>
   <header-i18n></header-i18n>
</div>

创建资源文件

在src/assets/i18n下创建en-US.json,ja-JP.json,zh-CN.json

{
    "menu.lang": "语言",
    "menu.storage":"清理本地缓存",
    "menu.fullsrceenOut":"退出全屏",
    "menu.fullsrceen":"全屏",
    "menu.loginOut":"退出登录",
     "public.queryLoad":"搜索",
     "public.reSet":"重置",
     "}
          

好了,文件完了。总结一下

 类似资料: