有角度的i18国际化,以编程方式更改语言



通过这个链接,我试图在我的Angular 6应用程序中实现i18国际化,以便用英语和意大利语翻译我的html模板中的一些文本和日期时间。

https://next.angular.io/guide/i18n

我知道这个功能由三个阶段组成:

  1. 定义翻译文本。没问题,我创建了一个src/locale文件夹,其中有两个文件messages.en.xlf(和message.it.xlf(;以下是en版本的示例。

    你好i18n!(英语(此示例的介绍标头用户欢迎
  2. 将此文本链接到带有适当标签的html页面,这里也没有问题,在我的app.translations.html.中有我的示例标签

    你好i18n!

现在,我读了(3。phase(在启动期间本地化应用程序(在Angular.json文件中进行一些编辑,并使用配置选项启动ng-server(;但是,与此相反,我会以编程方式更改应用程序的语言。换句话说,我想要一个像这样的命令

SwitchAppLanguage('en')

例如,用户可以通过按钮自行更改,或者应用程序可以读取浏览器默认语言。我该怎么做?

编辑

我试着用这种方式编辑我的angular.json文件

"configurations": {
"production": {
"i18nFile": "src/locale/messages.it.xlf",
"i18nFormat": "xlf",
"i18nLocale": "it",
(...)

而且,在ng buildng serve之后,我希望看到意大利语文本,但它没有发生(并且应用程序启动和服务正确(。我做错了什么?

我用这种方式解决了开发模式的这个问题。也许有人能从中受益。

这只是一个临时解决方案,直到Angular在ivy i18n中提供此功能。

缺点:只有当语言文件生成为JSON:-(

polyfills.ts:

import { loadTranslations } from '@angular/localize';
import { isDevMode } from '@angular/core';
// All translation objects: must be json files for runtime-conditions! (XLF not supported)
import * as fr from "./i18n/messages.fr.json";
import * as nl from "./i18n/messages.nl.json";
import * as en from "./i18n/messages.json";

// Non-official translation loader to switch languages at runtime in development mode
if(isDevMode()){
let translations = {};
let lang = localStorage.getItem("lang");
if(lang === "fr"){
translations = fr;
} else if (lang === "nl"){
translations = nl;
} else{
translations = en;
}
// load translations at runtime
loadTranslations(translations['default']['translations']);
}

因此,如果您使用JIT,您可以使用webpackloader来热交换语言文件:

main.ts

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { getTranslationProviders } from './app/providers/i18n.provider';
import { LocaleService } from './app/services/locale.service';
if ( environment.production ) {
enableProdMode();
}
const locale = new LocaleService();
locale.getLocale().then( ( localeValue ) => {
getTranslationProviders( localeValue ).then( providers => {
platformBrowserDynamic().bootstrapModule( AppModule, { providers } )
.catch( err => console.log( err ) );
} );
} );

i18n.provider

import { TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core';
declare const require;
export function getTranslationProviders( locale: string ): Promise<any[]> {
// Get the locale id as arugment or from the global
//
const localeValue = locale || document[ 'locale' ] as string;

// return no providers if fail to get translation file for locale
//
const noProviders: Object[] = [];
// No locale or AU, doesn't require translation
//
if ( !localeValue || localeValue === 'au' ) {
return Promise.resolve( noProviders );
}
try {
const translations = require( `raw-loader!../../locale/messages.${ localeValue }.xlf` );
return Promise.resolve( [
{ provide: TRANSLATIONS, useValue: translations },
{ provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }
] );
} catch ( error ) {
console.error( error );
return Promise.resolve( noProviders );
}
}

本地服务

import { WindowRef } from 'app/services/windowRef.service';
import { environment } from 'environments/environment';

@Injectable()
export class LocaleService {
_locale: string;
set locale( val: string ) {
this._locale = val;
}
get locale() {
return this._locale;
}

constructor() {
this.setLocale();
}
setLocale() {
const winRef = new WindowRef();
this.locale = ( environment.countryLookup[ document.location.hostname ] || 'au' ).toLowerCase();
const match = document.location.search.match( /au|nz/ );
if ( match ) {
this.locale = match.shift();
}
// store locale in document
//
winRef.nativeWindow.document.locale = this.locale;
}
getLocale(): Promise<string> {
return Promise.resolve( this.locale );
}
}

你必须对它进行一些重构,以匹配你的项目,但我希望你能领会要点。在Ivy支持适当的语言切换之前,这可能是一个解决方案。

最新更新