Для привязки состояния формы в Angular к селекторам ngrx, следует выполнить несколько шагов.
1. Установите необходимые зависимости:
Angular:
npm install @ngrx/store @ngrx/effects
ngrx:
npm install @ngrx/store @ngrx/effects @ngrx/entity
2. Создайте файлы для действий, редукторов и эффектов:
mkdir app/store cd app/store touch form.actions.ts form.reducer.ts form.effects.ts form.selectors.ts
3. В файле form.actions.ts
определите действия, которые будут использоваться для изменения состояния формы:
import { createAction, props } from '@ngrx/store'; export const updateInputValue = createAction( '[Form] Update Input Value', props<{ controlName: string, value: any }>() ); export const submitForm = createAction( '[Form] Submit Form' );
4. В файле form.reducer.ts
создайте начальное состояние и определите редуктор для обработки действий:
import { createReducer, on } from '@ngrx/store'; import { updateInputValue, submitForm } from './form.actions'; export interface FormState { inputValue: string; // Здесь можно добавить другие поля, соответствующие вашей форме } export const initialState: FormState = { inputValue: '', // Инициализируйте значения других полей по мере необходимости }; export const formReducer = createReducer( initialState, on(updateInputValue, (state, { controlName, value }) => { return { ...state, [controlName]: value }; }), on(submitForm, (state) => { // Обработка отправки формы return state; }) );
5. В файле form.effects.ts
создайте эффекты, которые будут вызывать побочные эффекты при определенных действиях:
import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { map, tap } from 'rxjs/operators'; import { updateInputValue, submitForm } from './form.actions'; import { Router } from '@angular/router'; @Injectable() export class FormEffects { updateInputValue$ = createEffect(() => this.actions$.pipe( ofType(updateInputValue), map(({ controlName, value }) => { // Выполните здесь побочные эффекты в зависимости от состояния формы }) ), { dispatch: false } ); submitForm$ = createEffect(() => this.actions$.pipe( ofType(submitForm), tap(() => { // Обработка отправки формы this.router.navigate(['/success']); // Пример перенаправления после успешной отправки формы }) ), { dispatch: false } ); constructor( private actions$: Actions, private router: Router ) {} }
6. В файле form.selectors.ts
определите селекторы для доступа к состоянию формы:
import { createFeatureSelector, createSelector } from '@ngrx/store'; import { FormState } from './form.reducer'; export const selectFormState = createFeatureSelector<FormState>('form'); export const selectInputValue = createSelector( selectFormState, (state: FormState) => state.inputValue );
7. В вашем компоненте импортируйте необходимые модули, селекторы и действия:
import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; import { updateInputValue, submitForm } from './store/form.actions'; import { selectInputValue } from './store/form.selectors'; @Component({ selector: 'app-form', template: ` <input type="text" [value]="inputValue | async" (input)="updateInput($event.target.value)" /> <button (click)="submit()">Submit</button> ` }) export class FormComponent { inputValue = this.store.select(selectInputValue); constructor(private store: Store) {} updateInput(value: string) { this.store.dispatch(updateInputValue({ controlName: 'inputValue', value })); } submit() { this.store.dispatch(submitForm()); } }
В результате, у вас будет форма, привязанная к состоянию ngrx. Вы сможете обновлять значения полей формы с помощью действий и отслеживать состояние формы с помощью селекторов. Кроме того, вы можете определить побочные эффекты для выполнения дальнейших действий при изменении состояния формы.