Множественная асинхронная замена строк в RxJS - PullRequest
0 голосов
/ 14 апреля 2020

В приложении Angular у меня есть:

  • текст, в который я хочу перевести несколько ключей ресурсов
  • массив ключей ресурсов ("IS_LESS_THAN", "IS_GREATER_THAN", etc...)
  • массив языков ("EN, NL, FR", etc..)
  • служба, которая может переводить один ключ ресурса. Служба облегчает то, что при изменении выбранного языка она выдает новое значение через наблюдаемое.

Асинхронный является сложной частью. Я не могу сделать простой string.replace () для текста с помощью для l oop, потому что это будет работать только синхронно.

Как перевод может быть выполнен с использованием Rx JS? У меня есть следующий код, но застрял в конце:

    const text = '....... 3 IS_LESS_THAN 5 ........';
    const keys = ['IS_LESS_THAN', 'IS_GREATER_THAN', ....... ];

    const translatedText$ = of(keys).pipe(
       switchMap((key) =>
           this.localizationService.translate(key).pipe( // Will update its value when the current language changes
               map((value) => ({
                   // Store the original key/value combination to do the replace
                   key,
                   value,
               }))
         )
        // PROBLEM: How to replace each key in the text and return the result?
        // I tried reduce, but how to combine the accumulator and the value?
        reduce((acc, val) => {
            return val[0].replace(val[1], );
        })

Ответы [ 2 ]

0 голосов
/ 22 апреля 2020

Это было проще, чем ожидалось. Подвох заключался в том, чтобы сначала объединить результаты перевода, используя combineLatest. С этого момента все переводы доступны в списке substitutions в одном элементе наблюдаемой. Больше не нужно уменьшать несколько наблюдаемых предметов:

    return combineLatest(
        keys.map((key) =>
            this.localizationService.translate(key)))
        ).pipe(map((substitutions) => replace(text, substitutions)));

0 голосов
/ 15 апреля 2020

Вам необходимо указать начальное начальное значение, которое в вашем случае, вероятно, равно text.

reduce((translatedText, translation) => {
  return translatedText.replace(translation.key, translation.value);
}, text)

Вам также следует подумать об изменении switchMap на mergeMap, если вы хотите, чтобы все ваши ключи для перевода: https://ncjamieson.com/avoiding-switchmap-related-bugs/

...