我正在尝试创建一个方法,该方法将接受字符串键并使用 translate.instant(parameter) 返回翻译后的字符串值。问题是它返回键(参数)。如果找不到翻译,通常会返回。我认为问题是在加载器加载翻译之前调用了方法。
我的 app.module.ts 进口:
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [HttpClient]
}
})
createTranslateLoader 函数:
export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
在我的应用程序组件中:
constructor(public translate: TranslateService){
translate.setDefaultLang('en');
translate.use('en');
}
当我使用管道在 html 中翻译时,它工作正常。
您正在使用
TranslateHttpLoader
,它会在请求翻译时发出 HTTP 请求 - translate.use('en')
。如果您在 HTTP 调用返回之前调用instant(messageKey)
方法,ngx-translate 将返回密钥,因为它还没有翻译。所以你应该使用 get(messageKey)
方法来获取翻译 - 它是异步的并返回一个 Observable
:
this.translateService.get('hello.world').subscribe((translated: string) => {
console.log(res);
//=> 'Hello world'
// You can call instant() here
const translation = this.translateService.instant('something.else');
//=> 'Something else'
});
只有当您确定翻译已经加载(如代码示例中)时,您才可以使用
instant
方法,或者您可以编写自定义同步翻译加载器并在任何地方使用instant
。
您只能在加载翻译文件时使用TranslateService。 如果你想安全地使用 TranslateService.instant 你可以写一个角度解析器。 解析器等待执行您的组件代码,直到可观察返回一个值。
这是代码:
------------------------解析器------------------------ --------------
@Injectable()
export class TranslationLoaderResolver {
constructor(private translate: TranslateService, private languageService: SetLanguageService){
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any>{
let lang = this.languageService.getSessionCurrentLanguage()
let reloadTranslation: boolean = false
if(lang===null || lang===undefined || lang==='null'){
this.languageService.inizializeLanguage()
lang = this.languageService.getSessionCurrentLanguage()
reloadTranslation = true
}
if(this.translate.instant("last.dummy")==='last.dummy'){
reloadTranslation = true
}
if(reloadTranslation==true){
return new Observable((observer: Observer<any>) => {
this.translate.getTranslation(lang).subscribe({
next: (elem) => {
//console.log(elem)
},
complete: () => {
observer.next(true);
observer.complete();
},
error: (e) => {
console.error(e)
observer.next(true);
observer.complete();
}
})
});
}
return of(true)
}
}
--------------------路由模块--------------------
let routing = RouterModule.forChild([
{path: "dashboard", component: DashboardComponent, resolve: {model: TranslationLoaderResolver},
children: [
........//here you can omit Resolver
},
}
-----文件 i18n-----
In last line add the line----> "last.dummy"="dummy translation"
SetLanguageService
是一种服务,您可以创建它来存储所使用的语言,例如在会话存储中(例如 lang 是“it”、“en”)。
这是
SetLanguageService
的例子(我的应用只有意大利语,en lang有评论)
const LANG_SESS_STRING_MAP: string = "language_choosen";
@Injectable()
export class SetLanguageService {
constructor(private translate: TranslateService){
}
inizializeLanguage(): void{
if( this.getSessionCurrentLanguage()==null || this.getSessionCurrentLanguage()=="null" ){
this.setBrowserLanguage();
}else{
this.changeLang(this.getSessionCurrentLanguage())
}
}
private setBrowserLanguage(): void{
this.translate.addLangs(['it'/*, 'en'*/]);
let defaultLang = this.getLanguage(this.translate.getBrowserLang());
this.translate.setDefaultLang( defaultLang );
this.translate.use( defaultLang );
this.saveSessionCurrentLanguage(defaultLang);
}
saveSessionCurrentLanguage(lang: string): void{
localStorage.setItem(LANG_SESS_STRING_MAP, lang);
}
getSessionCurrentLanguage(): string{
return localStorage.getItem(LANG_SESS_STRING_MAP);
}
private getLanguage(lang: string): string {
if(lang == null || lang === undefined){
return 'it';
}
switch(lang){
case 'it': {
return 'it';
}
/*case 'en' :{
return 'en';
}*/
default : {
return 'it';
}
}
}
changeLang(lang: string) {
this.translate.langs=[];
this.translate.addLangs(['it'/*, 'en'*/]);
let toSet = this.getLanguage(lang);
this.saveSessionCurrentLanguage(toSet);
this.translate.use(toSet);
}
}
我希望这可以帮助
您也可以拨打虚拟电话,等待回复。响应后,每个即时呼叫都会正常工作,因为它肯定会加载翻译。
async ngOnInit() {
await this.translate.get('dummyTranslation').toPromise().then();
this.translate.instant("realTranslation");
像这样用 onReady 包装你的 $translate.instant :
$translate.onReady(函数(){ //代码在这里 })
提醒一下:记得清空localStorage。这是我的错误。