【问题标题】:ngx-translate .instant returns key instead of valuengx-translate .instant 返回键而不是值
【发布时间】:2018-02-23 06:22:31
【问题描述】:

我正在尝试使用 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');
}

在我的 app.component 中:

constructor(public translate: TranslateService){
   translate.setDefaultLang('en');
   translate.use('en');
}

当我使用管道在 html 中翻译时,它可以正常工作。

【问题讨论】:

  • 使用 .instant 添加您的代码,或者将 .instant() 替换为 .stream() 这对我有用
  • 你以什么方式使用.stream(),因为当我添加它时,它说'Observable'类型的参数不能分配给'string'类型的参数
  • 请添加您的代码:
  • this.translateService.stream(event['title']) .subscribe((title) => this.titleService.setTitle(title))
  • 不能让它工作,我不是那么有经验,你能帮帮我吗,我想翻译打字稿中的字符串,翻译的关键是 General.Add...我该怎么做溪流?谢谢。

标签: angular typescript loader ngx-translate


【解决方案1】:

您正在使用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

【讨论】:

  • 我之前尝试过 get 并且它可以工作,但我不能在方法中使用它,因为从异步调用返回一些东西是有风险的,因为你在获得值之前就返回了。我正在考虑编写自定义加载程序,但我不知道如何。你有什么主意吗?回答问题
  • 您可以在project website 找到同步加载程序的示例。最简单的方法是在加载器本身中将翻译定义为 Map 对象或基本 JSON 对象,如示例中所示。
  • 我按照示例中显示的方式实现了它,但现在我认为它找不到我的带有翻译的文件夹,因为到处都只写了键,我错过了什么吗?
  • 如果应该在你的加载器中指定你所有的键/值对 - 你在一个单独的 JSON 文件中的那些,因为 ngx-translate 不再从 JSON 文件中加载它们。如果问题仍然存在,最好的机会是从 ngx-translate 调试加载器和/或 TranslateService 类。
【解决方案2】:

您只能在加载翻译文件时使用 TranslateService。 如果您想安全地使用 TranslateService.instant,您可以编写一个角度解析器。 解析器等待执行你的组件代码,直到 observable 返回一个值。

这是代码:

--------------解析器---------- ---------------

@Injectable()
export class TranslationLoaderResolver {

    constructor(private translate: TranslateService){
    }

    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any>{
        return this.translate.get("last.dummy"); //
    }

}

----------路由模块------

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"

希望对你有帮助

【讨论】:

  • 我喜欢这个使用解析器的解决方案,效果很好
  • 非常感谢您的回答。它确实有效。:)
【解决方案3】:

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

$translate.onReady(function () { //这里的代码 })

【讨论】:

  • 据我所知,ngx-translate没有onReady这样的机制。您可以在记录/解释的地方粘贴参考吗?
【解决方案4】:

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

【讨论】:

    【解决方案5】:

    您也可以进行虚拟呼叫,并等待响应。响应后,每个即时调用都会起作用,因为它肯定会加载翻译。

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

    【讨论】:

    • angular 不会等待异步 ngOnInit 完成
    • 这个想法是在真正的翻译之前进行等待虚拟调用。把它放在 ngOnInit() 或者你要在哪里使用翻译都没关系
    • 你可以将 ur ngOnInit 更改为 async,这实际上完成了这项工作
    猜你喜欢
    • 2021-11-09
    • 1970-01-01
    • 2016-02-05
    • 1970-01-01
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-06
    相关资源
    最近更新 更多