ngx-translate with Angular universal 在翻译参数化值时出现问题
ngx-translate with Angular universal has problems translating parameterised value
我正在使用 Angular universal 将我的 Angular 10 应用程序迁移到 SSR,我在转换参数化值时遇到了 ngx-translate 的问题。
我有翻译
Bei Kauf von {quantity}
这个数量是我们组件的一个属性,我们通常把它翻译成
{{ 'LABEL' | translate: {quantity: 1} }}
我们将看到 Bei Kauf von 1
但是对于 SSR,它根本无法翻译。我在页面上看到 Bei Kauf von {quantity}
。我检查了很多论坛,但没有看到可能的解决方案。任何帮助将不胜感激。
这是我的翻译-server.loader.ts
import { join } from 'path';
import { Observable } from 'rxjs';
import { TranslateLoader } from '@ngx-translate/core';
import {
makeStateKey,
StateKey,
TransferState
} from '@angular/platform-browser';
import * as fs from 'fs';
export class TranslateServerLoader implements TranslateLoader {
constructor(
private transferState: TransferState,
private prefix: string = 'i18n',
private suffix: string = '.json'
) {}
public getTranslation(lang: string): Observable<any> {
return new Observable((observer) => {
const assets_folder = join(
process.cwd(),
'dist',
'my-app',
'browser',
'assets',
this.prefix
);
const jsonData = JSON.parse(
fs.readFileSync(`${assets_folder}/${lang}${this.suffix}`, 'utf8')
);
// Here we save the translations in the transfer-state
const key: StateKey<number> = makeStateKey<number>(
`transfer-translate-${lang}`
);
this.transferState.set(key, jsonData);
observer.next(jsonData);
observer.complete();
});
}
}
export function translateServerLoaderFactory(transferState: TransferState) {
return new TranslateServerLoader(transferState);
}
翻译-browser.loader.ts
import { Observable } from 'rxjs';
import { TranslateLoader } from '@ngx-translate/core';
import {
makeStateKey,
StateKey,
TransferState
} from '@angular/platform-browser';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { HttpClient } from '@angular/common/http';
export class TranslateBrowserLoader implements TranslateLoader {
constructor(private http: HttpClient, private transferState: TransferState) {}
public getTranslation(lang: string): Observable<any> {
const key: StateKey<number> = makeStateKey<number>(
`transfer-translate-${lang}`
);
const data = this.transferState.get(key, null);
// First we are looking for the translations in transfer-state,
// if none found, http load as fallback
if (data) {
return new Observable((observer) => {
observer.next(data);
observer.complete();
});
} else {
return new TranslateHttpLoader(this.http).getTranslation(lang);
}
}
}
export function translateBrowserLoaderFactory(
httpClient: HttpClient,
transferState: TransferState
) {
return new TranslateBrowserLoader(httpClient, transferState);
}
app.server.module.ts
import { NgModule } from '@angular/core';
import { ServerModule, ServerTransferStateModule } from '@angular/platform-server';
import { FlexLayoutServerModule } from '@angular/flex-layout/server';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { translateServerLoaderFactory } from './shared/loaders/translate-server.loader';
import { TransferState } from '@angular/platform-browser';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { EnvironmentService } from '~shared/services/environment.service';
@NgModule({
imports: [
AppModule,
ServerModule,
ServerTransferStateModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: translateServerLoaderFactory,
deps: [TransferState]
}
}),
FlexLayoutServerModule,
],
providers: [EnvironmentService],
bootstrap: [AppComponent],
})
export class AppServerModule {}
app.module.ts
imports: [
....,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: translateBrowserLoaderFactory,
deps: [HttpClient, TransferState]
}
}),
]
注意:它适用于所有其他在翻译中没有任何参数化值的人
应该是双花括号
Bei Kauf von {{quantity}}
我正在使用 Angular universal 将我的 Angular 10 应用程序迁移到 SSR,我在转换参数化值时遇到了 ngx-translate 的问题。
我有翻译
Bei Kauf von {quantity}
这个数量是我们组件的一个属性,我们通常把它翻译成
{{ 'LABEL' | translate: {quantity: 1} }}
我们将看到 Bei Kauf von 1
但是对于 SSR,它根本无法翻译。我在页面上看到 Bei Kauf von {quantity}
。我检查了很多论坛,但没有看到可能的解决方案。任何帮助将不胜感激。
这是我的翻译-server.loader.ts
import { join } from 'path';
import { Observable } from 'rxjs';
import { TranslateLoader } from '@ngx-translate/core';
import {
makeStateKey,
StateKey,
TransferState
} from '@angular/platform-browser';
import * as fs from 'fs';
export class TranslateServerLoader implements TranslateLoader {
constructor(
private transferState: TransferState,
private prefix: string = 'i18n',
private suffix: string = '.json'
) {}
public getTranslation(lang: string): Observable<any> {
return new Observable((observer) => {
const assets_folder = join(
process.cwd(),
'dist',
'my-app',
'browser',
'assets',
this.prefix
);
const jsonData = JSON.parse(
fs.readFileSync(`${assets_folder}/${lang}${this.suffix}`, 'utf8')
);
// Here we save the translations in the transfer-state
const key: StateKey<number> = makeStateKey<number>(
`transfer-translate-${lang}`
);
this.transferState.set(key, jsonData);
observer.next(jsonData);
observer.complete();
});
}
}
export function translateServerLoaderFactory(transferState: TransferState) {
return new TranslateServerLoader(transferState);
}
翻译-browser.loader.ts
import { Observable } from 'rxjs';
import { TranslateLoader } from '@ngx-translate/core';
import {
makeStateKey,
StateKey,
TransferState
} from '@angular/platform-browser';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { HttpClient } from '@angular/common/http';
export class TranslateBrowserLoader implements TranslateLoader {
constructor(private http: HttpClient, private transferState: TransferState) {}
public getTranslation(lang: string): Observable<any> {
const key: StateKey<number> = makeStateKey<number>(
`transfer-translate-${lang}`
);
const data = this.transferState.get(key, null);
// First we are looking for the translations in transfer-state,
// if none found, http load as fallback
if (data) {
return new Observable((observer) => {
observer.next(data);
observer.complete();
});
} else {
return new TranslateHttpLoader(this.http).getTranslation(lang);
}
}
}
export function translateBrowserLoaderFactory(
httpClient: HttpClient,
transferState: TransferState
) {
return new TranslateBrowserLoader(httpClient, transferState);
}
app.server.module.ts
import { NgModule } from '@angular/core';
import { ServerModule, ServerTransferStateModule } from '@angular/platform-server';
import { FlexLayoutServerModule } from '@angular/flex-layout/server';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { translateServerLoaderFactory } from './shared/loaders/translate-server.loader';
import { TransferState } from '@angular/platform-browser';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { EnvironmentService } from '~shared/services/environment.service';
@NgModule({
imports: [
AppModule,
ServerModule,
ServerTransferStateModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: translateServerLoaderFactory,
deps: [TransferState]
}
}),
FlexLayoutServerModule,
],
providers: [EnvironmentService],
bootstrap: [AppComponent],
})
export class AppServerModule {}
app.module.ts
imports: [
....,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: translateBrowserLoaderFactory,
deps: [HttpClient, TransferState]
}
}),
]
注意:它适用于所有其他在翻译中没有任何参数化值的人
应该是双花括号
Bei Kauf von {{quantity}}