angular
July 31
Использование Flux-паттерна в Angular
Flux — это архитектурный паттерн, используемый для создания одностороннего потока данных в приложениях. Он был разработан Facebook и используется для управления состоянием в приложениях, особенно когда они становятся сложными. В Angular для работы со стором можно использовать Flux-подобные библиотеки, такие как NgRx.
Основные концепции Flux
- Store: Хранит состояние приложения и логику управления этим состоянием. В Angular это может быть реализовано с помощью NgRx Store, который представляет собой реактивное хранилище для управления состоянием приложения.
- Actions: Объекты, которые описывают изменения в состоянии. Actions отправляются в стор для инициирования изменений состояния.
- Dispatcher: Центральный узел, который принимает actions и распределяет их в сторы. В NgRx это представлено метками действия, которые передаются в редукторы.
- Reducers: Чистые функции, которые принимают текущее состояние и action, затем возвращают новое состояние. В NgRx редукторы определяют, как изменяется состояние в ответ на actions.
- Selectors: Функции для получения данных из store. Они помогают избежать прямого доступа к состоянию и способствуют созданию более модульного кода.
Пример использования Flux-подхода с NgRx в Angular
1. Установка NgRx
Для начала необходимо установить необходимые пакеты NgRx:
npm install @ngrx/store @ngrx/effects @ngrx/store-devtools
2. Определение Actions
Создайте файл actions.ts
для определения действий:
codeimport { createAction, props } from '@ngrx/store'; export const addTodo = createAction('[Todo List] Add Todo', props<{ todo: string }>()); export const removeTodo = createAction('[Todo List] Remove Todo', props<{ index: number }>());
3. Создание Reducers
Создайте файл reducers.ts
для определения редукторов:
import { createReducer, on } from '@ngrx/store'; import { addTodo, removeTodo } from './actions'; export const initialState: string[] = []; const _todoReducer = createReducer( initialState, on(addTodo, (state, { todo }) => [...state, todo]), on(removeTodo, (state, { index }) => state.filter((_, i) => i !== index)) ); export function todoReducer(state: any, action: any) { return _todoReducer(state, action); }
4. Регистрация Store в модуле
Добавьте стор в корневой модуль app.module.ts
:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { StoreModule } from '@ngrx/store'; import { todoReducer } from './reducers'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, StoreModule.forRoot({ todos: todoReducer }) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
5. Использование Store в компоненте
Теперь вы можете использовать стор в компоненте:
import { Component } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { addTodo, removeTodo } from './actions'; interface AppState { todos: string[]; } @Component({ selector: 'app-root', template: ` <div> <h1>Todo List</h1> <input #todoInput> <button (click)="add(todoInput.value); todoInput.value=''">Add Todo</button> <ul> <li *ngFor="let todo of todos$ | async; let i = index"> {{ todo }} <button (click)="remove(i)">Remove</button> </li> </ul> </div> ` }) export class AppComponent { todos$: Observable<string[]>; constructor(private store: Store<AppState>) { this.todos$ = this.store.select('todos'); } add(todo: string) { this.store.dispatch(addTodo({ todo })); } remove(index: number) { this.store.dispatch(removeTodo({ index })); } }