How to extend ngx-translate pipe

拜拜、爱过 提交于 2019-12-11 07:44:10

问题


I want to extend ngx-translate's pipe to make it potentially multi purpose within my app.

My pipe:

import { Pipe, PipeTransform } from '@angular/core';
import { TranslatePipe } from "@ngx-translate/core";

@Pipe({
  name: 'msg'
})

export class MsgPipe extends TranslatePipe implements PipeTransform {
  transform(value: any, args: any[]): any {
    return super.transform(value, args)
  }
}

In order to wait for the relevant translate modules to load, I have used Angular's APP_INITIALIZER:

app.module:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { HttpClientModule, HttpClient } from '@angular/common/http';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { appRoutes } from './app.routes';
import { AppComponent } from './root/app.component';
import { PageNotFoundComponent } from './shared/components/page-not-found/page-not-found.component';
import { HomePageComponent } from './shared/components/home-page/home-page.component';
import { MsgPipe } from './shared/pipes/msg.pipe';
import { ChangeDetectorRef } from '@angular/core';
import { TranslateModule, TranslateLoader } from "@ngx-translate/core";
import { Injector, APP_INITIALIZER } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { LOCATION_INITIALIZED } from '@angular/common';

export function HttpLoaderFactory(http: HttpClient) {
    return new TranslateHttpLoader(http);
}


export function appInitializerFactory(translate: TranslateService, injector: Injector) {
    return () => new Promise<any>((resolve: any) => {
        const locationInitialized = injector.get(LOCATION_INITIALIZED, Promise.resolve(null));
        locationInitialized.then(() => {
            const langToSet = 'en'
              translate.setDefaultLang('en');
            translate.use(langToSet).subscribe(() => {
                console.info(`Successfully initialized '${langToSet}' language.'`);
            }, err => {
                console.error(`Problem with '${langToSet}' language initialization.'`);
            }, () => {
                resolve(null);
            });
        });
    });
}

@NgModule({
    declarations: [
        AppComponent,
        PageNotFoundComponent,
        HomePageComponent,
        MsgPipe
    ],
    imports: [
        BrowserModule,
        RouterModule.forRoot(appRoutes),
        HttpClientModule,
        TranslateModule.forRoot({
            loader: {
                provide: TranslateLoader,
                useFactory: HttpLoaderFactory,
                deps: [HttpClient]
            }
        }),
    ],
    providers: [
        {
            provide: APP_INITIALIZER,
            useFactory: appInitializerFactory,
            deps: [TranslateService, Injector],
            multi: true
        }
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

(The code above was taken from here)

My pipe still doesn't work unless pure is set to false, causing multiple unnecessary calls. No errors, it just doesn't change the content.


回答1:


You do not any extra library for translations. As an example, you only need a pipe file translation-pipe.ts file and translation.provder.ts file and you can extend whatever you want. Please check the below files

translation-pipe.ts

import { Pipe, PipeTransform } from '@angular/core';

import {TranslateProvider} from '../../providers/translate/translate';

@Pipe({
  name: 'translation',
})
export class TranslationPipe implements PipeTransform {

  constructor(private _translateService: TranslateProvider) { }

  transform(value: string, ...args) {
    return this._translateService.instant(value);
  }
}

TranslateProvider.ts

import {Injectable} from '@angular/core';
import {LANG_EN_TRANS} from './languages/en';
import {LANG_TR_TRANS} from './languages/tr';

@Injectable()
export class TranslateProvider {

  private _currentLang: string;
  // If you want to use dictionary from local resources
  private _dictionary = {
    'en': LANG_EN_TRANS,
    'tr': LANG_TR_TRANS
  };

  // inject our translations
  constructor( private _db: DbProvider) { }

  public get currentLang() {
     if ( this._currentLang !== null) {
       return this._currentLang;
     } else return 'en';
  }

  public use(lang: string): void {
    this._currentLang = lang;
  } // set current language

  // private perform translation
  private translate(key: string): string {

   // if u use local files
    if (this._dictionary[this.currentLang] && this._dictionary[this.currentLang][key]) {
      return this._dictionary[this.currentLang][key];
    } else {
      return key;
    }

   // if u do not want local files then get a json file from database and add to dictionary
  }

  public instant(key: string) { return this.translate(key); }
}

Here private translate() function is main function to change the local key to language. You can import local files like en.ts, sp.ts, au.ts etc. or you can modify this function to connect database and get the key value pairs... Example of local translation file is

en.ts

export const LANG_EN_TRANS = {
  'about': 'About',
}

or

tr.ts

export const LANG_TR_TRANS = {
  'about': 'Hakkinda',
}

Have a nice coding...




回答2:


If you do the pipe impure works... but I think that is not the best way to solve that.

@Pipe({
  name: 'msg',
  pure: false
})
export class TranslationPipe extends TranslatePipe {


来源:https://stackoverflow.com/questions/46431752/how-to-extend-ngx-translate-pipe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!