3

ngx-translate のパイプを拡張して、アプリ内で潜在的に多目的にしたいと考えています。

私のパイプ:

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)
  }
}

関連する変換モジュールがロードされるのを待つために、Angular の 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 { }

(上記のコードはhereから取得されました)

pure が false に設定されていない限り、私のパイプはまだ機能せず、複数の不要な呼び出しが発生します。エラーはありません。コンテンツは変更されません。

4

5 に答える 5

0

translatepipe 自体は不純です (参照: https://github.com/ngx-translate/core/blob/master/projects/ngx-translate/core/src/lib/translate.pipe.ts )。反応する必要があるためです。 translations-observable への変更について。

また、instant(...) の代わりに super.transform(key, ...args) を呼び出す必要があります。このアプローチは、私たちのプロジェクトで機能しました。または、代わりにインスタントを使用する必要がある理由を述べてください。

于 2020-11-20T13:59:16.527 に答える
0

TranslatePipeからngx-translateは不純です。そして、それには理由があります。したがって、次のようにも設定pureする必要がありfalseます。

@Pipe({
  name: 'msg',
  pure: false
})

これで作業するには十分ですが、私の答えを少し拡張します。

翻訳パイプは、一度だけ翻訳して完了するようには設計されていません。1 つまたは複数の言語の翻訳をプリロードしても、後でユーザーが言語を切り替える可能性があります。実際には、今日の時点で 3 つの異なるイベントを処理する必要があります。

  • 言語変更
  • デフォルト言語の変更
  • 翻訳が変わる

ここで、元の翻訳パイプのソースを見ると、これらのイベントで翻訳された値が既に更新されていることがわかります。すべてのイベントがupdateValue()メソッドを呼び出します。https://github.com/ngx-translate/core/blob/master/projects/ngx-translate/core/src/lib/translate.pipe.tsを参照してください。次にupdateValue()、再レンダリングを要求するために、パイプをダーティとしてマークします。

于 2021-07-16T13:18:08.707 に答える