Solución:
Para establecer la configuración regional del servicio, debe agregar LOCALE_ID
proveedor con fábrica para app.module
, como en la respuesta de @AmolBhor
{
provide: LOCALE_ID,
deps: [SettingsService], //some service handling global settings
useFactory: (settingsService) => settingsService.getLanguage() //returns locale string
}
Lamentablemente, no puede cambiar el idioma de DatePipe JIT. El compilador angular requiere LOCALE_ID
durante el arranque.
Hay algunos informes de errores para Angular:
- https://github.com/angular/angular/issues/15039 (cerrado – no resuelto)
- https://github.com/angular/angular/issues/16960 (cerrado con solución en los comentarios)
Hay varias soluciones para esto:
Solución alternativa n. ° 1
Reinicio del módulo angular:
let _platformRef: NgModuleRef<Object>;
if(_platformRef) { _platformRef.destroy(); }
platformBrowserDynamic(providers)
.bootstrapModule(AppModule, {providers})
.then(platformRef => {
_platformRef = platformRef;
})
* Esto no funcionará para Hybrid Angular / AngularJS ya que no hay forma de destruir AngularJS usando UpgradeModule.
Solución alternativa n. ° 2
Para sobrescribir DatePipe, NumberPipe, lo que necesite:
@Pipe({name: 'datepipe', pure: true})
export class MyDatePipe implements PipeTransform {
transform(value: any, pattern?: string): string | null {
// transform value as you like (you can use moment.js and format by locale_id from your custom service)
return DateUtils.format(value);
}
}
Solución alternativa n. ° 3
Para usar la biblioteca que ya maneja la localización con tuberías personalizadas, por ejemplo:
- https://github.com/urish/angular2-moment
- https://github.com/robisim74/angular-l10n
Solución alternativa n. ° 4
Cada pipa que usa LOCALE_ID
tiene campo privado lugar o _lugar, por lo que puede anular este campo en las canalizaciones en el cambio de idioma, ya que hay una instancia de canalización.
Eso funcionará porque TypeScript es solo azúcar de sintaxis para JavaScript. Y en JavaScript no hay campos privados.
También recuerde procesar la detección de cambios en la aplicación utilizando tick()
método en ApplicationRef.
@Injectable()
export class DynamicLocaleService {
private i18nPipes: PipeTransform[];
constructor(
datePipe: DatePipe,
currencyPipe: CurrencyPipe,
decimalPipe: DecimalPipe,
percentPipe: PercentPipe,
private applicationRef: ApplicationRef,
) {
this.i18nPipes = [
datePipe,
currencyPipe,
decimalPipe,
percentPipe,
]
}
setLocale(lang: string): void {
this.i18nPipes.forEach(pipe => {
if(pipe.hasOwnProperty("locale")) {
pipe["locale"] = lang;
} else if (pipe.hasOwnProperty("_locale")) {
pipe["_locale"] = lang
}
})
this.applicationRef.tick()
}
}
Solución alternativa n. ° 5
Para recargar la aplicación cuando se cambia de idioma.
window.location.reload()
Desafortunadamente, todo lo anterior son soluciones alternativas.
Pero también hay otra solución: puede tener varios paquetes para cada idioma, lo que probablemente será un mejor enfoque ya que la aplicación será más rápida. Pero esta solución no es aplicable a todas las aplicaciones y no responde a la pregunta.
Utilizando providers
puede cambiar su configuración regional predeterminada en su NgModule
. Para hacer esto, debe importar LOCALE_ID de angular / core y recuperar su idioma local para pasar el mismo a los proveedores.
import { LOCALE_ID } from '@angular/core';
@NgModule({
imports: [//your imports],
providers: [
{ provide: LOCALE_ID, useValue: "en-US" }
]
})
...
...
{
provide: LOCALE_ID,
deps: [SettingsService], //some service handling global settings
useFactory: (settingsService) => settingsService.getLanguage() //returns locale string
}
Espero que esto te ayudará.
Tenga su servicio como
import { Injectable } from '@angular/core';
@Injectable()
export class LocaleService {
//Chosse Locale From This Link
//https://github.com/angular/angular/tree/master/packages/common/locales
constructor() { }
private _locale: string;
set locale(value: string) {
this._locale = value;
}
get locale(): string {
return this._locale || 'en-US';
}
public registerCulture(culture: string) {
debugger;
if (!culture) {
return;
}
switch (culture) {
case 'en-uk': {
this._locale="en";
console.log('Application Culture Set to English');
break;
}
case 'zh-hk': {
this._locale="zh-Hant";
console.log('Application Culture Set to Traditional Chinese');
break;
}
case 'zh-cn': {
this._locale="zh-Hans";
console.log('Application Culture Set to Simplified Chinese');
break;
}
default: {
this._locale="en";
console.log('Application Culture Set to English');
break;
}
}
}
}
Y en App.module.ts
primera localización de importación que necesita, digamos
import localeEN from '@angular/common/locales/en';
import localezhHant from '@angular/common/locales/zh-Hant';
import localezhHans from '@angular/common/locales/zh-Hans';
Que en la sección de proveedores
{
provide: LOCALE_ID,
deps: [LocaleService],
useFactory: (LocaleService: { locale: string; }) => LocaleService.locale
}
Al final
registerLocaleData(localeEN);
registerLocaleData(localezhHant);
registerLocaleData(localezhHans);
Espero que ayude a alguien
si desea cambiar la configuración regional dinámicamente, inyecte LocaleService en su componente deseado y use el método registerCulture, pase su cultura requerida a este