Пример использования redux ngrx
В этом уроке я расскажу Вам как можно начать работу с redux в angular (2+).
Установите Angular CLI как написано в инструкции т.е. наберите в консоли
Npm install –g @angular/cli (если у вас нет Npm установите его https://nodejs.org/en/)
Npm install –g @angular/cli
После установки перейдите в какую-нибудь папку, например, GIT если она у вас есть на диске (cd D:\GIT) и внутри этой папки добавьте сам проект.
Ng new my-dream-app
Система некоторое врмя будет подгружить зависимости на ваш компьютер, придется немного подождать. После чего зайдите во внутрь вашего проекта.
cd my-dream-app
Теперь в корне проекта подгрузим еще несколько зависимостей Наберите команду.
npm install @ngrx/core @ngrx/store @ngrx/store-devtools @ngrx/effects --save
Можно ограничится первыми двумя, но я рекомендую установить сразу всё. После того как «проект нашей мечты» будет добавлен в папку можете открыть его в редакторе. Я открою проект в visual studio code. Теперь всё что нам нужно это настроить проект для работы с redux. Добавим в проект папку redux куда будем помещать всё связанное с инфраструктурой redux. Внутри папки добавим еще одну папку reducers – тут мы будет хранить наши редьюсеры.
Добавим файл helloReducer.ts и поместим следующий код
import { Action } from "@ngrx/store"; export interface helloState { msg: string; } const initialState: helloState = { msg: "Сорри тут пусто :(" }; export function helloReducer(state = initialState, action: Action): helloState { switch (action.type) { case "ADD_HELLO": return { msg: "Hello " } case "ADD_WORLD": return { msg: state.msg + "World!" } case "REMOVE_HELLO_WORLD": return { msg: "" } default: return state; } }
В данном случае у нас одно состояние (helloState) на один редьсер как добавить больше состояний покажу позже. В данном случае всё что делает редьюсер это просто добавляет слова hello world. Давайте протестируем как это будет выглядеть на деле.
Еще немного настроек. Перейдите в файл app.module.ts – наш стартовый модуль где начинается наше angular 2+ приложение. Добавьте в imports модуль StoreModule из библиотеки @ngrx/store и наш с вам единственный на данный момент редьюсер helloReducer.
Файл app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { StoreModule } from "@ngrx/store"; import { helloReducer } from "app/redux/reducers/helloReducer"; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, StoreModule.provideStore(helloReducer) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Еще рекомендую добавить модуль, для тестирования который позволит нам запустить мощный инструмент для отслеживания работы Redux devtools chrome extention
Для этого добавим еще
StoreDevtoolsModule.instrumentOnlyWithExtension()
В итоге весь наш модуль теперь выглядит так
Файл app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { StoreModule } from "@ngrx/store"; import { StoreDevtoolsModule } from "@ngrx/store-devtools"; import { helloReducer } from "app/redux/reducers/helloReducer"; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, StoreModule.provideStore(helloReducer), StoreDevtoolsModule.instrumentOnlyWithExtension() ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Теперь мы спокойно можем вызвать наш Store в любом компоненте.
Добавим store через механизм внедрения зависимостей. Обратите внимание что мы не задумываемся как всё это работает модули ngrx уже настроены под всё необходимое за нас.
Поэтому добавим три метода в компонент
Файл app.component.ts
import { Component } from '@angular/core'; import { Store } from "@ngrx/store"; import { helloState } from "app/redux/reducers/helloReducer"; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; constructor(private store: Store<helloState>) { } onAddHello() { this.store.dispatch({ type: "ADD_HELLO" }) } onAddWorld() { this.store.dispatch({ type: "ADD_WORLD" }) } onRemoveHelloWorld() { this.store.dispatch({ type: "REMOVE_HELLO_WORLD" }) } }
А также реализуем их в представление
Файла app.component.html
<div style="text-align:center"> <h1> {{title}} </h1> </div> <div> <button (click)="onAddHello()">AddHello</button> <button (click)="onAddWorld()">AddWorld</button> <button (click)="onRemoveHelloWorld()">RemoveHelloWorld</button> </div>
Теперь просто запустим наше прилежание. Наберите команду
ng serve –open
В итоге наше приложение запуститься во вкладке браузера по адресу http://localhost:4200/
Давайте сразу откроем расширение для мониторинга работы redux devtools (Redux devtools chrome extention) в google chrome.
Переключитесь на вкладку “state”
И мы увидим наше сообщения по умолчанию «Сорри тут пусто :(»
Нажмите последовательно на кнопки addHello, addworld, removeHelloWorld мы увидим в DevTools как меняется состояние.
Здорово значит всё работает!
Но как отобразить данные изменения в представление. Подписываемся на изменения состояния в angular redux ngrx. Всё что нужно сделать это подписаться на изменения к нашему хранилищу или store. В конструкторе класса AppComponent добавьте инструкцию.
store.subscribe(result => this.title = result.msg)
В итоге файл app.component.ts
import { Component } from '@angular/core'; import { Store } from "@ngrx/store"; import { helloState } from "app/redux/reducers/helloReducer"; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app'; constructor(private store: Store<helloState>) { store.subscribe(result => this.title = result.msg) } onAddHello() { this.store.dispatch({ type: "ADD_HELLO" }) } onAddWorld() { this.store.dispatch({ type: "ADD_WORLD" }) } onRemoveHelloWorld() { this.store.dispatch({ type: "REMOVE_HELLO_WORLD" }) } }
Запустим приложение. Как совместить работу redux ngrx и запросы к базе мы посмотрим в след. Статье.
Исходники тут (https://github.com/rusrc/redux_with_ngrx_super_simple)