【问题标题】:How to update the current language with ngx-translate?如何使用 ngx-translate 更新当前语言?
【发布时间】:2021-01-09 00:06:57
【问题描述】:

我正在使用 Electron 10 和 Angular 10,也使用 ngx-translate。我想在用户在下拉菜单中切换语言后更新当前视图/页面的翻译。

在开发过程中,我当然会使用 Angular 及其 HTTP 服务器,这就是我使用 HttpLoaderFactory 的原因。但对于生产版本,我使用自定义 translateFactory,它通过 TranslateUniversalLoader 加载 JSON 文件。这样可以吗?

无论是在开发版本还是生产版本中,我都可以在不重新启动应用程序的情况下更新字符串。我有一个下拉菜单,更改时我只需调用this.translate.use(lang)。视图应该重新加载吗?这里的预期行为是什么?

我注册模块如下:

export class TranslateUniversalLoader implements TranslateLoader {
       
  constructor() {
  }

  public getTranslation(lang: string): Observable<any> {
      return of(TRANSLATIONS[lang]);
    }
  }
  
  export function translateFactory() {
    return new TranslateUniversalLoader();
  }
}
...

@NgModule({
  declarations: [AppComponent],
  imports: [
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: isProductionBuild() ? translateFactory : HttpLoaderFactory,
        deps: [HttpClient]
      },
      isolate : false
    })

【问题讨论】:

    标签: angular electron ngx-translate


    【解决方案1】:

    我认为您是从类似延迟加载的子模块中调用this.translate.use(lang),这些子模块未注入到导入TranslateModule 的根模块中。要从延迟加载模块中调用它,请创建一个名为 LanguageService 的服务:

    @Injectable({ providedIn: 'root' })
    export class LanguageService {
       language$ = new BehaviorSubject(null);
    
       applyLang(lang: string) {
          this.language$.next(lang);
       }
    }
    

    并观察language$app.component.ts 的变化:

    ...
    export class AppComponent {
       constructor(private languageService: LanguageService, private translate: TranslateService) {
          this.languageService.language$.subscribe(lang => {
              if (lang) {
                  this.translate.use(lang); // Use lang here
              }
          });
       }
    }
    

    现在您可以使用 LanguageService 更改任何延迟加载模块的语言。

    ...
    constructor(private languageService: LanguageService) {}
    
    updateLanguage() {
       this.languageService.applyLang('en'); // Call from components belonging to lazyload modules
    }
    

    否则,通过直接从 LanguageService 调用 translate.use 来简化流程。

    @Injectable({ providedIn: 'root' })
    export class LanguageService {
       constructor(private translate: TranslateService) {}
    
       applyLang(lang: string) {
          this.translate.use(lang);
       }
    }
    

    【讨论】:

    • 哇,非常感谢您的详细回答!我认为你真的在做某事。我按照描述实现了所有内容(+LanguageService 的注册),并且可以确认language$.subscribe 是用相应的语言调用的。但仍然没有更新 UI。你知道我在这里可能缺少什么吗?
    • 我也将这个库用于我的 Angular 通用项目。所以我在写这篇文章之前很快尝试了它并确认它有效。你能和我分享完整的 app.module.ts 吗?
    • 我刚刚意识到我没有正确加载语言:-o。你让我今天一整天都感觉很好!我有机会在这个答案上悬赏吗?
    • “开始赏金”按钮位于问题评论区下方
    猜你喜欢
    • 2017-07-30
    • 1970-01-01
    • 2019-09-13
    • 1970-01-01
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    • 2018-04-14
    • 1970-01-01
    相关资源
    最近更新 更多