ng2-translate — строки перевода не обновляются в компонентах с обнаружением изменений OnPush

Когда я впервые меняю язык своего приложения, служба перевода делает запрос на файл, представляющий новый язык. Строки моих «умных» компонентов правильно отражают обновление, НО любые «чистые/глупые» компоненты этого не делают, они остаются в предыдущем язык. Однако, как только новый языковой файл загружен в кеш, и я продолжаю менять языки, все работает нормально.

Кажется, что любой чистый компонент не разрешает обновления из ответа ajax для нового языкового файла, он будет правильно менять язык только тогда, когда файл уже загружен в кеш. Опять же, это только для компонентов, использующих ChangeDetectionStrategy.OnPush.

Я понимаю, что changeDetection использует Inputs и Observables в тупых компонентах, но я не очень хорошо разбираюсь в каналах в этом случае. Возможно, я что-то упускаю?

ОБНОВИТЬ

Мне удалось взломать исправление, это не здорово, но работает. Это конструктор в моем сервисе, который обертывает сервис Translate.

Я проверяю, есть ли в кеше языковой json-файл для языка, который я собираюсь выбрать. Если у меня его нет, я использую метод «reloadLang» в ng2-translate, чтобы пойти и получить его. Как только он у меня есть, я использую пустой тайм-аут, а затем вызываю «translate.use». Где-то есть проблема со временем, потому что если я уберу тайм-аут, это не сработает. Если у меня уже есть файл перевода, на который я собираюсь переключиться, я просто использую translate.use как обычно, и все работает нормально.

constructor(private translate: TranslateService, public store: Store<any>) {
// this language will be used as a fallback when a translation isn't found in the current language
translate.setDefaultLang('en');
// subscribe to changes
store.select('i18n').subscribe((state: MultilingualStateI) => {
  // update ng2-translate which will cause translations to occur wherever the TranslatePipe is used in the view
  if (this.translate.getLangs() && (this.translate.getLangs().indexOf(state.lang) > -1)) {
    this.translate.use(state.lang)
  } else {
    this.translate.reloadLang(state.lang).take(1).subscribe(() => {
      setTimeout(() => this.translate.use(state.lang), 0);
    });
  }
});

}

Я не совсем уверен, что здесь происходит, но, похоже, это сочетание использования ChangeDetectionStrategy.OnPush и свежего ответа на запрос файла перевода. Если кто-то еще видит это, пожалуйста, добавьте свой вклад.


person HomeBrew    schedule 08.07.2016    source источник
comment
Я застрял с той же проблемой. Какой параметр Store вы передаете своему конструктору?   -  person Isthar    schedule 11.10.2016


Ответы (1)


Я застрял с этой проблемой. У меня есть несколько графиков (я использую ng2-charts), и когда я изменил язык (например, с en на es), все метки были обновлены, кроме тех, которые относятся к диаграмме. Для обновления моих диаграмм с новым языком мне пришлось снова изменить язык на es (поэтому дважды щелкните, чтобы изменить язык в первый раз).

Прочитав вашу проблему и обходной путь, я проверил ее, и проблема, как вы указали, в кеше. При первом изменении языка загружается JSON, но, поскольку его не было в кеше, не все компоненты переводятся (в моем случае диаграммы не обновлялись должным образом). Во второй раз, когда вы переключаетесь на тот же язык, метки уже находятся в кеше, поэтому он работает правильно.

Я исправил это, загрузив все доступные языки при инициализации службы:

constructor(private translate: TranslateService) {
    var navigatorLanguage = (window.navigator.userLanguage || window.navigator.language).toLowerCase().split("-")[0];
    // this language will be used as a fallback when a translation isn't found in the current language
    translate.setDefaultLang(navigatorLanguage);
    // the lang to use, if the lang isn't available, it will use the current loader to get them
    translate.use(navigatorLanguage)
    // Hack to load all languages
    // If we don't do this, the first time we change language not all elements are properly translated
    translate.reloadLang('en')
    translate.reloadLang('es')
}

В моем случае у меня есть только эти два языка. Если их больше, возможно, какой-нибудь цикл for будет полезен для перезагрузки каждого языка :)

person Isthar    schedule 11.10.2016
comment
{{Спасибо | Перевести}} Грасиас - person nicolas.leblanc; 27.01.2017
comment
На самом деле это сработало для меня, хотя мне пришлось вызвать перевод, используйте ПОСЛЕ перевода.reloadLang (чтобы исправить некоторые ошибки, когда часть загруженной страницы будет на испанском языке, а другая часть будет на английском (когда при загрузке страницы выбран английский язык)) - person nicolas.leblanc; 27.01.2017
comment
translate.reloadLang(lang) отлично работает, спасибо +1 - person elporfirio; 21.09.2017