Вопрос или проблема
Итак, я использую 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
не сбрасывает уже загруженные результаты.
-
Модификация функции получение страниц:
Убедитесь, что передаваемые критерии поиска обрабатывает пагинацию правильно. Например, если у вас уже есть результаты на первой странице, загружайте их, а затем добавляйте новую страницу.
-
Оптимизация подписки:
Убедитесь, что вы не отписываетесь от маршрутизации, прежде чем завершить все операции. Используйте оператор
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.