Пагинация в Angular с NgRX?

Пагинация является важной частью многих веб-приложений, поскольку она позволяет разбивать большие объемы данных на более управляемые части. Вариант использования пагинации с Angular и NgRX не является сложным и требует нескольких шагов.

NgRx - это библиотека для управления состоянием приложения в Angular, которая основана на идее о хранилище Redux. Она включает в себя несколько разных концепций, таких как действия (actions), селекторы (selectors) и эффекты (effects), которые помогают организовать код и упростить управление состоянием.

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

1. Создайте действия (actions), которые будут использоваться для изменения состояния для пагинации, например, LoadPage, NextPage, PreviousPage и т. д.

import { createAction, props } from '@ngrx/store';

export const loadPage = createAction('[Pagination] Load Page', props<{ pageNumber: number }>());
export const nextPage = createAction('[Pagination] Next Page');
export const previousPage = createAction('[Pagination] Previous Page');

2. Создайте редуктор (reducer), который будет обрабатывать эти действия и изменять состояние приложения соответствующим образом. Например:

import { createReducer, on } from '@ngrx/store';
import { loadPage, nextPage, previousPage } from './pagination.actions';

export interface PaginationState {
  pageNumber: number;
}

export const initialPaginationState: PaginationState = {
  pageNumber: 1,
};

export const paginationReducer = createReducer(
  initialPaginationState,
  on(loadPage, (state, { pageNumber }) => ({ ...state, pageNumber })),
  on(nextPage, (state) => ({ ...state, pageNumber: state.pageNumber + 1 })),
  on(previousPage, (state) => ({ ...state, pageNumber: state.pageNumber - 1 })),
);

3. Создайте селекторы (selectors), которые позволят вам получать информацию о текущей странице пагинации из состояния приложения. Например:

import { createSelector } from '@ngrx/store';
import { PaginationState } from './pagination.reducer';

export const selectPaginationState = (state: AppState) => state.pagination;

export const selectCurrentPage = createSelector(
  selectPaginationState,
  (paginationState: PaginationState) => paginationState.pageNumber,
);

4. Реализуйте компоненты, которые будут использовать пагинацию и взаимодействовать с пагинационными действиями и селекторами для управления состоянием. Например:

import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { loadPage, nextPage, previousPage } from './pagination.actions';
import { selectCurrentPage } from './pagination.selectors';

@Component({
  selector: 'app-pagination',
  template: `
    <button (click)="previousPage()">Previous</button>
    <span>{{ currentPage$ | async }}</span>
    <button (click)="nextPage()">Next</button>
  `,
})
export class PaginationComponent implements OnInit {
  currentPage$ = this.store.select(selectCurrentPage);

  constructor(private store: Store) {}

  ngOnInit() {
    this.loadCurrentPage();
  }

  loadCurrentPage() {
    this.store.dispatch(loadPage({ pageNumber: this.currentPage$ }));
  }

  previousPage() {
    this.store.dispatch(previousPage());
    this.loadCurrentPage();
  }

  nextPage() {
    this.store.dispatch(nextPage());
    this.loadCurrentPage();
  }
}

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

import { StoreModule } from '@ngrx/store';
import { paginationReducer } from './pagination.reducer';

@NgModule({
  imports: [
    StoreModule.forRoot({
      pagination: paginationReducer,
    }),
  ],
})
export class AppModule {}

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

<app-pagination></app-pagination>

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