首頁 web前端 js教程 Angular使用ngrx/store做狀態管理

Angular使用ngrx/store做狀態管理

Jan 21, 2021 pm 05:21 PM
angular 狀態管理

本篇文章跟大家介紹一下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/store

2. 建立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分離出來如何處理?


3. 註冊store

根模組:

app/app.module.ts

import { 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(&#39;count&#39;)); 
    // 从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(&#39;count&#39;)); 
    // 从app.module.ts中获取count状态流
    stream.subscribe((res)=>{
          this.count = res;
      })
  }
登入後複製

為了管理方便, 一般會把type , state, actions,reducers 分開來管理

5 如果想把action分離出來如何處理?

新建\app\store\actions.ts 檔案
  1. import { Injectable } from &#39;@angular/core&#39;;
    import { INCREMENT, DECREMENT, RESET } from &#39;./types&#39;;
    
    @Injectable()
    export class CounterAction{
        // Add=function(){}
        Add(){
            return { type: INCREMENT }
        }
    }
    
    // 就只这样导出是不行的
    // export function Add1(){
    //     return { type: INCREMENT }
    // }
    登入後複製
在根模組app.module.ts 註冊
  1. import {CounterAction} from &#39;./store/actions&#39;;
    
    ... 
    
    providers: [CounterAction],
    登入後複製
在元件中使用– article.component.ts
  1. import {CounterAction} from &#39;../../store/actions&#39;;
    
    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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

如何在Ubuntu 24.04上安裝Angular 如何在Ubuntu 24.04上安裝Angular Mar 23, 2024 pm 12:20 PM

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

angular學習之詳解狀態管理器NgRx angular學習之詳解狀態管理器NgRx May 25, 2022 am 11:01 AM

這篇文章帶大家深入了解angular的狀態管理器NgRx,介紹一下NgRx的使用方法,希望對大家有幫助!

淺析angular中怎麼使用monaco-editor 淺析angular中怎麼使用monaco-editor Oct 17, 2022 pm 08:04 PM

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

一文探究Angular中的服務端渲染(SSR) 一文探究Angular中的服務端渲染(SSR) Dec 27, 2022 pm 07:24 PM

你知道 Angular Universal 嗎?可以幫助網站提供更好的 SEO 支援哦!

如何使用PHP和Angular進行前端開發 如何使用PHP和Angular進行前端開發 May 11, 2023 pm 04:04 PM

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

Angular元件及其顯示屬性:了解非block預設值 Angular元件及其顯示屬性:了解非block預設值 Mar 15, 2024 pm 04:51 PM

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

淺析Angular中的獨立組件,看看怎麼使用 淺析Angular中的獨立組件,看看怎麼使用 Jun 23, 2022 pm 03:49 PM

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

專案過大怎麼辦?如何合理拆分Angular項目? 專案過大怎麼辦?如何合理拆分Angular項目? Jul 26, 2022 pm 07:18 PM

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

See all articles