ngx-translate .instant 返回键而不是值

问题描述 投票:0回答:5

我正在尝试创建一个方法,该方法将接受字符串键并使用 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 中翻译时,它工作正常。

angular typescript loader ngx-translate
5个回答
53
投票

您正在使用

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


22
投票

您只能在加载翻译文件时使用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);
    }
    
}

我希望这可以帮助


4
投票

您也可以拨打虚拟电话,等待回复。响应后,每个即时呼叫都会正常工作,因为它肯定会加载翻译。

async ngOnInit() {
  await this.translate.get('dummyTranslation').toPromise().then();
  this.translate.instant("realTranslation");

0
投票

像这样用 onReady 包装你的 $translate.instant :

$translate.onReady(函数(){ //代码在这里 })


0
投票

提醒一下:记得清空localStorage。这是我的错误。

© www.soinside.com 2019 - 2024. All rights reserved.