Наблюдаемые данные потеряны при вызове API

Вопрос или проблема

Итак, я использую Spartacus в качестве основы для проекта. В Spartacus данные о продукте получаются с помощью этого метода поиска:

search(query: string | undefined, searchConfig?: SearchConfig): void {
  if (query) {
    this.store.dispatch(
      new ProductActions.SearchProducts({
        queryText: query,
        searchConfig: searchConfig,
      })
    );
  }
}

Теперь все эти данные передаются в Observable model$. В моем проекте мне нужно реализовать функцию “показать больше”, которая сохраняет отображение предыдущих элементов и отображает новые элементы. Когда я вызываю функцию:

getPageItems(pageNumber: number): void {
  this.routing
    .getRouterState()
    .subscribe((route) => {
      const routeCriteria = this.getCriteriaFromRoute(
        route.state.params,
        route.state.queryParams
      );
      const criteria = {
        ...routeCriteria,
        currentPage: pageNumber,
      };
      this.search(criteria);
    })
    .unsubscribe();
}

Это обновляет весь observable, и я теряю предыдущие элементы продукта. Как я могу отслеживать предыдущие элементы продукта и добавлять новые элементы продукта?

В вашем редюсере вам нужно будет добавить новые результаты поиска к существующему списку.

На данный момент ваш редюсер, вероятно, выглядит примерно так:

on(ProductActions.SearchProductsSuccess, (state, action) => ({
   ...state,
   searchResults: action.searchResults
}))

Для добавления новых результатов поиска попробуйте вместо этого:

on(ProductActions.SearchProductsSuccess, (state, action) => ({
   ...state,
   searchResults: [...state.searchResults, ...action.searchResults]
}))

Ответ или решение

Потеря наблюдаемых данных при вызове API в проекте на базе Spartacus

В проекте, использующем Spartacus, вы столкнулись с проблемой потери данных при вызове API для получения продуктов. Рассмотрим вашу ситуацию более подробно и предложим решения для сохранения предыдущих и добавления новых элементов.

Проблема

Вы используете метод search, чтобы инициировать поиск продуктов. Однако при вызове метода getPageItems, который обновляет состояние маршрута и вызывает поиск, все результаты старого поиска стираются. Это происходит из-за того, что ваш редюсер при обработке действия SearchProductsSuccess заменяет текущие результаты новыми.

Ваша текущая реализация редюсера может выглядеть следующим образом:

on(ProductActions.SearchProductsSuccess, (state, action) => ({
   ...state,
   searchResults: action.searchResults
}))

Данный подход подменяет массив результатов поиска новыми, тем самым теряя предыдущие результаты.

Решение

Чтобы избежать потери данных и обеспечить возможность добавления новых результатов к уже существующим, вам необходимо изменить логику вашего редюсера следующим образом:

on(ProductActions.SearchProductsSuccess, (state, action) => ({
   ...state,
   searchResults: [...state.searchResults, ...action.searchResults]
}))

Эта модификация обеспечивает конкатенацию новых результатов поиска к уже имеющимся, что позволяет вам сохранять состояние вашего списка продуктов.

Применение

В контексте вашей функции getPageItems, если вы хотите загружать дополнительные результаты для текущей страницы и при этом сохранять предыдущие, необходимо убедиться, что передача currentPage не сбрасывает уже загруженные результаты.

  1. Модификация функции получение страниц:

    Убедитесь, что передаваемые критерии поиска обрабатывает пагинацию правильно. Например, если у вас уже есть результаты на первой странице, загружайте их, а затем добавляйте новую страницу.

  2. Оптимизация подписки:

    Убедитесь, что вы не отписываетесь от маршрутизации, прежде чем завершить все операции. Используйте оператор take(1) для подписки, чтобы получать данные из маршрутов только один раз.

    Вот пример как можно реализовать функцию с учетом указанных предложений:

    getPageItems(pageNumber: number): void {
     this.routing.getRouterState()
       .pipe(take(1))
       .subscribe(route => {
         const routeCriteria = this.getCriteriaFromRoute(
           route.state.params,
           route.state.queryParams
         );
         const criteria = {
           ...routeCriteria,
           currentPage: pageNumber,
         };
         this.search(criteria);
       });
    }

Заключение

Следуя данным рекомендациям, вы сможете избежать потери наблюдаемых данных при вызове API. Модификация редюсера позволит вам накапливать результаты поиска, что обеспечит пользователям удобное взаимодействие с вашим приложением.

Не забывайте тестировать новые изменения и следить за производительностью при увеличении объема данных. Эти улучшения не только повысят пользовательский опыт, но и обеспечат более качественное управление состоянием в вашем приложении на базе Spartacus.

Оцените материал
Добавить комментарий

Капча загружается...