Angular使用ngrx/store做狀態管理
本篇文章跟大家介紹一下Angular ngrx/store狀態管理的使用。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。
相關教學推薦:《angular教學》
Angular中使用ngrx做狀態管理
簡介
ngrx/store的靈感來自Redux,是一款整合RxJS的Angular狀態管理庫,由Angular的佈道者Rob Wormald開發。它和Redux的核心思想相同,但使用RxJS實現觀察者模式。它遵循Redux核心原則,但專門為Angular而設計。
Angular中的狀態管理大部分可以被service接管,那麼在一些中大型的專案中,這樣做的弊端就會顯露出來,其中之一就是狀態流混亂,不利於後期維護,後來便藉鑒了redux的狀態管理模式並配上rxjs串流程式設計的特點形成了@ngrx/store這麼一個作用於Angular的狀態管理工具.
StoreModule:
StoreModule是@ngrx/store API中的一個模組,它被用來在應用程式模組中配置reducer。Action:
Action是狀態的改變。它描述了某個事件的發生,但是沒有指定應用的狀態如何改變。Store:
它提供了Store.select()和Store.dispatch()來與reducer協同工作。 Store.select()用來選擇一個selector,
Store.dispatch(
{
type:'add',
payload:{name:'111'}
}
)
用來向reducer分發action的類型。
@NgRx/Store 狀態管理的三個原則
首先,@NgRx/Store 同樣遵守Redux 的三個基本原則:
- 單一資料來源
這個原則是整個單頁應用的狀態透過object tree(物件樹)的形式儲存在store 裡面。
這個定義十分抽像其實就是把所有需要共享的資料透過javascript 物件的形式儲存下來
state = { application:'angular app', shoppingList:['apple', 'pear'] }
- state is read-only(狀態只能是唯讀形式)
#這個ngrx/store 核心之一就是使用者不能直接修改狀態內容。舉個例子,如果我們需要儲存了登入頁面狀態,狀態資訊需要記錄登入使用者的名字。當登入名字改變,我們不能直接修改狀態保存的使用者名字
state={'username':'kat'}, //用户重新登录别的账户为tom state.username = 'tom' //在ngrx store 这个行为是绝对不允许的
- changes are made with pure functions(只能透過呼叫函數來改變狀態)
由於不能直接需改狀態,ngrx/store 同時引進了一個叫做reducer(聚合器)的概念。透過reducer 來修改狀態。
function reducer(state = 'SHOW_ALL', action) { switch (action.type) { case 'SET_VISIBILITY_FILTER': return Object.assign({}, state ,newObj); default: return state } }
ngrx/store使用實例
#1.安裝@ngrx/store
##yarn add @ngrx/store2. 建立state, action, reducer
state 狀態: app\store\state.ts
//下面是使用接口的情况, 更规范 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; // 如果要管理多个状态,在这个接口中添加即可 } //这个是不用接口的情况 // export interface AppState { // count: number; // todos: any; // // 如果要管理多个状态,在这个接口中添加即可 // }
reducer app\store\reducer.ts
// reducer.ts,一般需要将state,action,reducer进行文件拆分 import { Action } from '@ngrx/store'; export const INCREMENT = 'INCREMENT'; export const DECREMENT = 'DECREMENT'; export const RESET = 'RESET'; const initialState = 0; // reducer定义了action被派发时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##如果需要把action 單獨提取出來, 參考後面的
5 如果想把action分離出來如何處理?根模組:
app/app.module.tsimport { NgModule } from '@angular/core'; import { StoreModule } from '@ngrx/store'; // StoreModule: StoreModule是@ngrx/storeAPI中的一个模块, // 它被用来在应用模块中配置reducer。 import {counterReducer} from './store/reducer'; @NgModule({ imports: [ StoreModule.forRoot({ count: counterReducer }), // 注册store ], }) export class AppModule {}
4. 使用store
在元件或服務中註入store進行使用
以app\module\article\article.component.ts 元件為例:
// 组件级别 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<number>; constructor(private store: Store<AppState>) { // 注入store this.count = store.pipe(select('count')); // 从app.module.ts中获取count状态流 } increment() { this.store.dispatch({ type: INCREMENT }); } decrement() { this.store.dispatch({ type: DECREMENT }); } reset() { this.store.dispatch({ type: RESET }); } }
範本頁面:
app\module\article\article.component.html<div class="state-count"> <button (click)="increment()">增加Increment</button> <div>Current Count: {{ count | async }}</div> <button (click)="decrement()">减少Decrement</button> <button (click)="reset()">Reset Counter</button> </div>
這裡使用了管道符async, 在子模組裡直接使用快報錯, 如果在子模組要實現資料的雙向綁定也會報錯,具體原因參考課件說明的問題: The pipe 'async' could not be found? 如何做到在範本頁面中不使用管道 來渲染頁面 ?
修改如下:
count: Observable<number>; constructor(private store: Store<AppState>) { // 注入store var stream = store.pipe(select('count')); // 从app.module.ts中获取count状态流 stream.subscribe((res)=>{ this.count = res; }) }
5 如果想把action分離出來如何處理?
新建\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 } } } // 就只这样导出是不行的 // export function Add1(){ // return { type: INCREMENT } // }
登入後複製
-
import {CounterAction} from './store/actions'; ... providers: [CounterAction],
登入後複製
- 更多程式相關知識,請造訪:程式設計學習
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做狀態管理的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

Angular.js是一種可自由存取的JavaScript平台,用於建立動態應用程式。它允許您透過擴展HTML的語法作為模板語言,以快速、清晰地表示應用程式的各個方面。 Angular.js提供了一系列工具,可協助您編寫、更新和測試程式碼。此外,它還提供了許多功能,如路由和表單管理。本指南將討論在Ubuntu24上安裝Angular的方法。首先,您需要安裝Node.js。 Node.js是一個基於ChromeV8引擎的JavaScript運行環境,可讓您在伺服器端執行JavaScript程式碼。要在Ub

angular中怎麼使用monaco-editor?以下這篇文章記錄下最近的一次業務中用到的 monaco-editor 在 angular 中的使用,希望對大家有幫助!

隨著網路的快速發展,前端開發技術也不斷改進與迭代。 PHP和Angular是兩種廣泛應用於前端開發的技術。 PHP是一種伺服器端腳本語言,可以處理表單、產生動態頁面和管理存取權限等任務。而Angular是一種JavaScript的框架,可以用來開發單一頁面應用程式和建構元件化的網頁應用程式。本篇文章將介紹如何使用PHP和Angular進行前端開發,以及如何將它們

Angular框架中元件的預設顯示行為不是區塊級元素。這種設計選擇促進了元件樣式的封裝,並鼓勵開發人員有意識地定義每個元件的顯示方式。透過明確設定CSS屬性 display,Angular組件的顯示可以完全控制,從而實現所需的佈局和響應能力。

這篇文章帶大家了解Angular中的獨立元件,看看怎麼在Angular中建立一個獨立元件,怎麼在獨立元件中導入已有的模組,希望對大家有幫助!

Angular專案過大,怎麼合理拆分它?以下這篇文章跟大家介紹一下合理分割Angular專案的方法,希望對大家有幫助!
