Ionic3 / Ngx-translate - 带外部的 TranslateHttpLoader URL
Ionic3 / Ngx-translate - TranslateHttpLoader with external URL
我在 app.module.ts 中使用 TranslateHttpLoader 从服务器加载翻译文件,如下所示:
export function createTranslateLoader(http: Http) {
return new TranslateHttpLoader(http, AppConfig.API_URL+'/static/i18n/', '.json');
}
@NgModule({
...
imports: [
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [Http]
}
}),
],
...
})
一切正常,但我想知道是否有一种方法可以在加载程序由于任何原因(服务器问题、网络连接等)无法检索语言文件时捕获事件并可能加载本地 json 带有一些默认翻译字符串的文件?
如果应用程序在第一次加载时无法获取语言文件,我想捕获此事件,并回退到最小的本地 json 文件以仅显示翻译的维护 page/error 页面或其他内容。
最后我写了一个自定义加载器来解决需求:
import { Injectable } from '@angular/core';
import { Headers, Http, Response } from "@angular/http";
import { TranslateLoader } from '@ngx-translate/core';
import { AppConfig } from "./config"
import { Observable } from 'rxjs/Observable';
@Injectable()
export class CustomTranslateLoader implements TranslateLoader {
contentHeader = new Headers({"Content-Type": "application/json","Access-Control-Allow-Origin":"*"});
constructor(private http: Http) {}
getTranslation(lang: string): Observable<any>{
var apiAddress = AppConfig.API_URL+"/static/i18n/"+ lang+".json";
return Observable.create(observer => {
this.http.get(apiAddress, { headers: this.contentHeader }).subscribe((res: Response) => {
observer.next(res.json());
observer.complete();
},
error => {
// failed to retrieve from api, switch to local
this.http.get("/assets/i18n/en.json").subscribe((res: Response) => {
observer.next(res.json());
observer.complete();
})
}
);
});
}
}
并在 app.module.ts
...
import { CustomTranslateLoader } from "../services/trans-loader"
...
@NgModule({
...
imports: [
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: CustomTranslateLoader,
deps: [Http]
}
}),
],
...
})
更新 Angular >= 4.3
由于新的 Angular 版本使用 HttpClient
而不是 Http
, 的更新和更短的版本将是:
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { TranslateLoader } from '@ngx-translate/core';
import { Observable } from 'rxjs/Observable';
import { catchError } from 'rxjs/operators';
import { AppConfig } from './config';
@Injectable()
export class CustomTranslateLoader implements TranslateLoader {
contentHeader = new HttpHeaders({
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
});
constructor(private httpClient: HttpClient) {}
getTranslation(lang: string): Observable<any> {
const apiAddress = AppConfig.API_URL + `/static/i18n/${lang}.json`;
return this.httpClient.get(apiAddress, { headers: this.contentHeader })
.pipe(
catchError(_ => this.httpClient.get(`/assets/i18n/en.json`))
);
}
}
更新 Angular 12+
- 创建新的自定义翻译加载程序
// loader/customTranslate.loader.ts
import { TranslateLoader } from '@ngx-translate/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';
const LOCAL_URL = 'http://your.url.blanik.me/api';
export class CustomTranslateLoader implements TranslateLoader {
constructor(private httpClient: HttpClient) {}
getTranslation(lang: string): Observable<any> {
const url = `${LOCAL_URL}/assets/i18n/${lang}.json`;
return this.httpClient.get(url).pipe(catchError((_) => this.httpClient.get(`/assets/i18n/en.json`)));
}
}
- 更新angular 应用程序模块
// app.module.ts
// {...}
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { HttpClient } from '@angular/common/http';
import { CustomTranslateLoader } from './loader/customTranslate.loader';
@NgModule({
declarations: [AppComponent, OtherComponent],
imports: [
BrowserModule,
// ...
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: CustomTranslateLoader,
deps: [HttpClient],
},
}),
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
- 为您的组件添加语言切换
<select class="form-control" #langauge (change)="translateSite(langauge.value)">
<option *ngFor="let localization of translateService.getLangs()" [value]="localization"
[selected]="localization === translateService.currentLang">
{{ localization }}
</option>
</select>
import { Component, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent{
title = 'your-app-name';
constructor(public translateService: TranslateService) {
translateService.addLangs(['en', 'fr', 'pl']);
translateService.setDefaultLang('en');
}
translateSite(langauge: string) {
this.translateService.use(langauge);
}
}
请记住在您的服务器上设置正确的 CORS and/or(推荐)将您的翻译文件保持在同一域下.
不要在 httpClient
中添加自定义 CORS headers。否则,浏览器将阻止读取文件。
干杯!
我在 app.module.ts 中使用 TranslateHttpLoader 从服务器加载翻译文件,如下所示:
export function createTranslateLoader(http: Http) {
return new TranslateHttpLoader(http, AppConfig.API_URL+'/static/i18n/', '.json');
}
@NgModule({
...
imports: [
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [Http]
}
}),
],
...
})
一切正常,但我想知道是否有一种方法可以在加载程序由于任何原因(服务器问题、网络连接等)无法检索语言文件时捕获事件并可能加载本地 json 带有一些默认翻译字符串的文件?
如果应用程序在第一次加载时无法获取语言文件,我想捕获此事件,并回退到最小的本地 json 文件以仅显示翻译的维护 page/error 页面或其他内容。
最后我写了一个自定义加载器来解决需求:
import { Injectable } from '@angular/core';
import { Headers, Http, Response } from "@angular/http";
import { TranslateLoader } from '@ngx-translate/core';
import { AppConfig } from "./config"
import { Observable } from 'rxjs/Observable';
@Injectable()
export class CustomTranslateLoader implements TranslateLoader {
contentHeader = new Headers({"Content-Type": "application/json","Access-Control-Allow-Origin":"*"});
constructor(private http: Http) {}
getTranslation(lang: string): Observable<any>{
var apiAddress = AppConfig.API_URL+"/static/i18n/"+ lang+".json";
return Observable.create(observer => {
this.http.get(apiAddress, { headers: this.contentHeader }).subscribe((res: Response) => {
observer.next(res.json());
observer.complete();
},
error => {
// failed to retrieve from api, switch to local
this.http.get("/assets/i18n/en.json").subscribe((res: Response) => {
observer.next(res.json());
observer.complete();
})
}
);
});
}
}
并在 app.module.ts
...
import { CustomTranslateLoader } from "../services/trans-loader"
...
@NgModule({
...
imports: [
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: CustomTranslateLoader,
deps: [Http]
}
}),
],
...
})
更新 Angular >= 4.3
由于新的 Angular 版本使用 HttpClient
而不是 Http
,
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { TranslateLoader } from '@ngx-translate/core';
import { Observable } from 'rxjs/Observable';
import { catchError } from 'rxjs/operators';
import { AppConfig } from './config';
@Injectable()
export class CustomTranslateLoader implements TranslateLoader {
contentHeader = new HttpHeaders({
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
});
constructor(private httpClient: HttpClient) {}
getTranslation(lang: string): Observable<any> {
const apiAddress = AppConfig.API_URL + `/static/i18n/${lang}.json`;
return this.httpClient.get(apiAddress, { headers: this.contentHeader })
.pipe(
catchError(_ => this.httpClient.get(`/assets/i18n/en.json`))
);
}
}
更新 Angular 12+
- 创建新的自定义翻译加载程序
// loader/customTranslate.loader.ts
import { TranslateLoader } from '@ngx-translate/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';
const LOCAL_URL = 'http://your.url.blanik.me/api';
export class CustomTranslateLoader implements TranslateLoader {
constructor(private httpClient: HttpClient) {}
getTranslation(lang: string): Observable<any> {
const url = `${LOCAL_URL}/assets/i18n/${lang}.json`;
return this.httpClient.get(url).pipe(catchError((_) => this.httpClient.get(`/assets/i18n/en.json`)));
}
}
- 更新angular 应用程序模块
// app.module.ts
// {...}
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { HttpClient } from '@angular/common/http';
import { CustomTranslateLoader } from './loader/customTranslate.loader';
@NgModule({
declarations: [AppComponent, OtherComponent],
imports: [
BrowserModule,
// ...
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: CustomTranslateLoader,
deps: [HttpClient],
},
}),
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
- 为您的组件添加语言切换
<select class="form-control" #langauge (change)="translateSite(langauge.value)">
<option *ngFor="let localization of translateService.getLangs()" [value]="localization"
[selected]="localization === translateService.currentLang">
{{ localization }}
</option>
</select>
import { Component, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent{
title = 'your-app-name';
constructor(public translateService: TranslateService) {
translateService.addLangs(['en', 'fr', 'pl']);
translateService.setDefaultLang('en');
}
translateSite(langauge: string) {
this.translateService.use(langauge);
}
}
请记住在您的服务器上设置正确的 CORS and/or(推荐)将您的翻译文件保持在同一域下.
不要在 httpClient
中添加自定义 CORS headers。否则,浏览器将阻止读取文件。
干杯!