小編給大家分享一下Angular怎么使用ngrx/store做狀態(tài)管理,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
創(chuàng)新互聯(lián)公司網(wǎng)絡(luò)公司擁有十載的成都網(wǎng)站開發(fā)建設(shè)經(jīng)驗(yàn),上1000家客戶的共同信賴。提供成都網(wǎng)站制作、成都做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設(shè)、網(wǎng)站開發(fā)、網(wǎng)站定制、買友情鏈接、建網(wǎng)站、網(wǎng)站搭建、響應(yīng)式網(wǎng)站開發(fā)、網(wǎng)頁設(shè)計(jì)師打造企業(yè)風(fēng)格,提供周到的售前咨詢和貼心的售后服務(wù)
Angular中使用ngrx做狀態(tài)管理
簡介
ngrx/store的靈感來源于Redux,是一款集成RxJS的Angular狀態(tài)管理庫,由Angular的布道者Rob Wormald開發(fā)。它和Redux的核心思想相同,但使用RxJS實(shí)現(xiàn)觀察者模式。它遵循Redux核心原則,但專門為Angular而設(shè)計(jì)。
Angular中的狀態(tài)管理大部分可以被service接管,那么在一些中大型的項(xiàng)目中,這樣做的弊端就會(huì)顯露出來,其中之一就是狀態(tài)流混亂,不利于后期維護(hù),后來便借鑒了redux的狀態(tài)管理模式并配上rxjs流式編程的特點(diǎn)形成了@ngrx/store這么一個(gè)作用于Angular的狀態(tài)管理工具.
StoreModule:
StoreModule是@ngrx/store API中的一個(gè)模塊,它被用來在應(yīng)用模塊中配置reducer。
Action:
Action是狀態(tài)的改變。它描述了某個(gè)事件的發(fā)生,但是沒有指定應(yīng)用的狀態(tài)如何改變。
Store:
它提供了Store.select()和Store.dispatch()來與reducer協(xié)同工作。Store.select()用于選擇一個(gè)selector,
Store.dispatch(
{
type:‘a(chǎn)dd’,
payload:{name:‘111’}
}
)
用于向reducer分發(fā)action的類型。
@NgRx/Store 狀態(tài)管理的三個(gè)原則
首先,@NgRx/Store 同樣遵守 Redux 的三個(gè)基本原則:
單一數(shù)據(jù)源
這個(gè)原則是整個(gè)單頁應(yīng)用的狀態(tài)通過object tree(對(duì)象樹)的形式存儲(chǔ)在store 里面。
這個(gè)定義十分抽象其實(shí)就是把所有需要共享的數(shù)據(jù)通過javascript 對(duì)象的形式存儲(chǔ)下來
state = { application:'angular app', shoppingList:['apple', 'pear'] }
state is read-only(狀態(tài)只能是只讀形式)
這個(gè) ngrx/store 核心之一就是用戶不能直接修改狀態(tài)內(nèi)容。 舉個(gè)例子,如果我們需要保存了登錄頁面狀態(tài),狀態(tài)信息需要記錄登錄用戶的名字。 當(dāng)?shù)卿浢指淖儯覀儾荒苤苯有薷臓顟B(tài)保存的用戶名字
state={'username':'kat'}, //用戶重新登錄別的賬戶為tom state.username = 'tom' //在ngrx store 這個(gè)行為是絕對(duì)不允許的
changes are made with pure functions(只能通過調(diào)用函數(shù)來改變狀態(tài))
由于不能直接需改狀態(tài),ngrx/store 同時(shí)引入了一個(gè)叫做reducer(聚合器)的概念。通過reducer 來修改狀態(tài)。
function reducer(state = 'SHOW_ALL', action) { switch (action.type) { case 'SET_VISIBILITY_FILTER': return Object.assign({}, state ,newObj); default: return state } }
ngrx/store使用實(shí)例
1.安裝@ngrx/store
yarn add @ngrx/store
2. 創(chuàng)建 state, action, reducer
state 狀態(tài):
app\store\state.ts
//下面是使用接口的情況, 更規(guī)范 export interface TaskList { id: number; text: string; complete: boolean; } export const TASKSAll: TaskList[] = [ {id: 1, text: 'Java Article 1', complete: false}, {id: 2, text: 'Java Article 2', complete: false} ] export interface AppState { count: number; todos: TaskList; // 如果要管理多個(gè)狀態(tài),在這個(gè)接口中添加即可 } //這個(gè)是不用接口的情況 // export interface AppState { // count: number; // todos: any; // // 如果要管理多個(gè)狀態(tài),在這個(gè)接口中添加即可 // }
reducer
app\store\reducer.ts
// reducer.ts,一般需要將state,action,reducer進(jìn)行文件拆分 import { Action } from '@ngrx/store'; export const INCREMENT = 'INCREMENT'; export const DECREMENT = 'DECREMENT'; export const RESET = 'RESET'; const initialState = 0; // reducer定義了action被派發(fā)時(shí)state的具體改變方式 export function counterReducer(state: number = initialState, action: Action) { switch (action.type) { case INCREMENT: return state + 1; case DECREMENT: return state - 1; case RESET: return 0; default: return state; } }
actions
如果需要把a(bǔ)ction 單獨(dú)提取出來, 參考 后面的
5 如果想把a(bǔ)ction分離出來如何處理?
3. 注冊store
根模塊:
app/app.module.ts
import { NgModule } from '@angular/core'; import { StoreModule } from '@ngrx/store'; // StoreModule: StoreModule是@ngrx/storeAPI中的一個(gè)模塊, // 它被用來在應(yīng)用模塊中配置reducer。 import {counterReducer} from './store/reducer'; @NgModule({ imports: [ StoreModule.forRoot({ count: counterReducer }), // 注冊store ], }) export class AppModule {}
4. 使用store
在組件或服務(wù)中注入store進(jìn)行使用
以 app\module\article\article.component.ts 組件為例:
// 組件級(jí)別 import { Component } from '@angular/core'; import { Store, select } from '@ngrx/store'; import { Observable } from 'rxjs'; import { INCREMENT, DECREMENT, RESET} from '../../store/reducer'; interface AppState { count: number; } @Component({ selector: 'app-article', templateUrl: './article.component.html', styleUrls: ['./article.component.css'] }) export class ArticleComponent { count: Observable; constructor(private store: Store ) { // 注入store this.count = store.pipe(select('count')); // 從app.module.ts中獲取count狀態(tài)流 } increment() { this.store.dispatch({ type: INCREMENT }); } decrement() { this.store.dispatch({ type: DECREMENT }); } reset() { this.store.dispatch({ type: RESET }); } }
模板頁面:
app\module\article\article.component.html
Current Count: {{ count | async }}
這里使用了 管道符 async, 在子模塊里直接使用快報(bào)錯(cuò) , 如果在子模塊要實(shí)現(xiàn) 數(shù)據(jù)的雙向綁定也會(huì)報(bào)錯(cuò),具體原因參照 課件說明的 問題: The pipe ‘a(chǎn)sync’ could not be found?
如何做到在模板頁面中不使用管道 來渲染頁面 ?
修改如下:
count: Observable; constructor(private store: Store ) { // 注入store var stream = store.pipe(select('count')); // 從app.module.ts中獲取count狀態(tài)流 stream.subscribe((res)=>{ this.count = res; }) }
為了管理方便, 一般會(huì)把 type , state, actions,reducers 分開來管理
5 如果想把a(bǔ)ction分離出來如何處理?
新建 \app\store\actions.ts 文件
import { Injectable } from '@angular/core'; import { INCREMENT, DECREMENT, RESET } from './types'; @Injectable() export class CounterAction{ // Add=function(){} Add(){ return { type: INCREMENT } } } // 就只這樣導(dǎo)出是不行的 // export function Add1(){ // return { type: INCREMENT } // }
在根模塊 app.module.ts 注冊
import {CounterAction} from './store/actions'; ... providers: [CounterAction],
在組件中使用 – article.component.ts
import {CounterAction} from '../../store/actions'; export class ArticleComponent implements OnInit { constructor( private action: CounterAction //注入CounterAction ) { } increment() { // this.store.dispatch({ type: INCREMENT }); //把 actions分離出去 this.store.dispatch(this.action.Add()); } }
以上是“Angular怎么使用ngrx/store做狀態(tài)管理”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!