Update translations in loader of ngx-translate

余生长醉 提交于 2020-04-11 09:40:28

问题


I am creating a custom Angular ngx-translate Loader which either gets translations from cache or from an API. The point where I am stuck is Case 2 (see code below):

Desired procedure:

  1. gets translations from cache (sync)
  2. returns cached translations (via observer)
  3. gets translations from api (async)
  4. compares cache and api (finds difference)
  5. sends updated version of translations <-- How?

This is what I got:

getTranslation(lang: string): Observable<any> {
    return new Observable(observer => {

      // get translations from cache + start getting translations from API
      const cachedTranslations = this.cacheService.getTranslation(lang);
      const apiTranslations = this.http.get(environment.translationApi + lang);


      if (cachedTranslations) {
        // CASE #1: return cached translations
        observer.next(cachedTranslations);
      }

      apiTranslations.subscribe(translations => {
        // CASE #2: if cached translations are not up to date
        // or dont exist, add new translations and reload lang
        if (JSON.stringify(translations) !== JSON.stringify(cachedTranslations)) {
          this.cacheService.setTranslations(lang, translations);
          observer.next(translations);
        }

        observer.complete();
      }, () => {
        observer.complete();
      });

    });
}

Using observer.next() works only once, even if it isn't completed yet. So how do I update the translations in Case 2 where an observer.next() already happend in Case 1?


回答1:


This answer might not be relevant to you anymore, since it's been a few months, but I'll just leave it here, in case anybody stumbles over this question in the future, just like I did, when I was looking for a solution to this problem:

So it seems like pushing two different values into the observable in the getTranslation function messes with ngx-translate - I found a work around though.

I'm not sure if this is the best way to do it, but it works and solves my problem, so I'm just gonna go ahead and use it.

CustomTranslateLoader:

getTranslation(lang: string): Observable<any> {
    const translations = new BehaviorSubject(undefined);          
    translations.next(JSON.parse(this.localStorageService.getItem('translations')));
    return translations;
}

loadTranslation(lang) {
    return this.blockpitApiService.get('/translations/' + lang);
}

app.component.ts

constructor(
    private translate: TranslateService,
    private translateService: CustomTranslateLoader,
    private localStorageService: LocalStorageService
) {

    language = translate.getBrowserLang();
    translate.setDefaultLang(language);

    // load translations from server and update translations
    this.translateService.loadTranslation(language).subscribe(response => {
        this.localStorageService.setItem('translations', JSON.stringify(response.data));
        translate.setTranslation(language, response.data);
        translate.use(language);
    });
 }

Since ngx-translate simply ignores when we push new translations into the observable, we can simply call translate.setTranslation(language, response.data) and translate.use(language), to update the values used when translating.
By calling this as soon as our api call is finished, we initially see the translation that are first set in getTranslation which ngx-translation calls automatically and the api translations as soon as they are available when we .subscribe to the function in our app.component.ts.

This might not be ideal but it works and seems like an ok workaround - at least to me.



来源:https://stackoverflow.com/questions/53558004/update-translations-in-loader-of-ngx-translate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!