Saltar al contenido

Cambiar dinámicamente la configuración regional para DatePipe en Angular 2

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

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *