日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ngrx学习笔记

發布時間:2023/12/13 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ngrx学习笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是ngrx
ngrx是Angular基于Rxjs的狀態管理,保存了Redux的核心概念,并使用RxJs擴展的Redux實現。使用Observable來簡化監聽事件和訂閱等操作。
在看這篇文章之前,已經假設你已了解rxjs和redux。
有條件的話請查看官方文檔進行學習理解。

所需包
ng add方式,會自動生成所需文件并在app.module.ts中導入,直接啟動項目即可,不報錯
?

ng add @ngrx/store ng add @ngrx/store-devtools ng add @ngrx/effects ng add @ngrx/router-store

Angular的流程

compone.ts定義變量a
改變a
(沒有數據請求的) this.a = '';
(有數據請求的) this.a = this.services.search()類似的寫法
用ngrx后的Angular的基本流程

寫action.ts:為要改變數據的操作定義不同action
寫effects.ts(有數據請求的):通過判斷action.type,來發起service
寫reducer.ts:判斷action.type,返回新的store數據
component.ts:從store取數據
最后,告訴應用程序,你寫了這玩意

項目簡介
本項目的兩個demo,都掛在example模塊中

計數器-沒有數據請求 app/example/container/counter.component.ts
1、先寫action(減和重置的action在代碼里面,可自行查看)
?

// app/example/actions/counter.actions.ts import { Action } from '@ngrx/store';export const INCREMENT = '[Counter] Increment'; export class IncrementAction implements Action {readonly type = INCREMENT;constructor() { } }export type Actions= IncrementAction;

2、寫reducer(由于加不需要發送網絡請求,就不寫effect)

// app/example/reducer/counter.reducer.ts import * as counter from '../actions/counter.actions'; // 定義接口,后續counter頁面如果有其他數據要保存,可以在這個State里面繼續添加,不要忘記在initialState也要加 export interface State {counter: number; } // 定義初始化數據 const initialState: State = {counter: 0 }; // 定義reducer 根據action type來處理狀態,改變對應數據 export function reducer(state = initialState, action: counter.Actions): State {switch (action.type) {case counter.INCREMENT: return {counter: state.counter + 1};default:return { ...state };} }export const getCounter = (state: State) => state.counter; // app/example/reducer/index.ts import {createFeatureSelector, createSelector} from '@ngrx/store';// 第二步 導入我們的reducer文件 import * as fromCounter from './counter.reducer';export interface State {counter: fromCounter.State; } export const reducers = {counter: fromCounter.reducer };// 將模塊example的所有數據掛在store上,命名為example,里面保存example模塊里面所有頁面的數據 export const getExampleState = createFeatureSelector<State>('example');// 計數器頁面 export const getCounterState = createSelector(getExampleState, (state: State) => state.counter); export const getCounterCounter = createSelector(getCounterState, fromCounter.getCounter);

3、在模塊中導入reduecer,這樣就可以運行

// app/example/example.module.tsimport {StoreModule} from '@ngrx/store'; import {reducers} from './reducer'; @NgModule({imports: [StoreModule.forFeature('example', reducers) // 這個才是關鍵哦] }) export class ExampleModule { }

4、到這一步了,我們的頁面就來操作并且取數據,增加啦

// src/example/container/counter.component.tsimport * as fromExample from '../../reducer'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import * as counterAction from '../../actions/counter.actions';export class CounterComponent {counter$: Observable<number>;constructor(private store: Store<fromExample.State>) {this.counter$ = store.select(fromExample.getCounterCounter);}increment() {this.store.dispatch(new counterAction.IncrementAction());} }

頁面

// app/example/container/counter.component.html <div class="container"><p class="title">計數器 沒有數據請求的ngrx demo</p><div class="btn-group"><button nz-button nzType="primary" (click)="increment()">加</button><span style="font-size: 18px;font-weight: bold">當前數:{{counter$ | async}}</span></div> </div>

npm run start看一下頁面效果吧

搜索圖書-有數據請求的 src/app/example/containers/book-manage/book-manage.component.ts
1、寫action (src/app/example/actions/book-manage.actions.ts)看注釋

import { Action } from '@ngrx/store'; import {Book} from '../model/book'; // 搜索,然后搜索成功,兩件事情,分兩個action export const SEARCH = '[Book Manage] Search'; export const SEARCH_COMPLETE = '[Book Manage] Search Complete'; // 搜索圖書需要帶書名稱來搜索,所以SearchAction有一個字符串類型的參數payload export class SearchAction implements Action {readonly type = SEARCH;constructor(public payload: string) { } } // 搜索出結果后,圖書的信息我們將其定義類型為Book,結果放在數組里面,所以SearchCompleteAction 的參數是Book類型數組 export class SearchCompleteAction implements Action {readonly type = SEARCH_COMPLETE;constructor(public payload: Book[]) { } } export type Actions= SearchAction| SearchCompleteAction;

2、寫reducer(src/app/example/reducer/book-manage.reducer.ts)

import * as bookManage from '../actions/book-manage.actions'; import {Book} from '../model/book'; // book-manage頁面我們暫時定義一個list變量,用了存搜索圖書的結果,后續如果有其他變量,繼續在里面加 export interface State {list: Book[]; } // 默認一開始搜索數據為空數組[] const initialState: State = {list: [] }; // 當搜索成功后,更新state里面的list值 export function reducer(state = initialState, action: bookManage.Actions): State {switch (action.type) {case bookManage.SEARCH_COMPLETE:return {...state,list: action.payload};default:return { ...state };} }export const getList = (state: State) => state.list;

3、更新reducer (src/app/example/reducer/index.ts)

import {createFeatureSelector, createSelector} from '@ngrx/store'; import * as fromCounter from './counter.reducer'; // 導入寫好的book-manage.reducer.ts import * as fromBookManage from './book-manage.reducer'; export interface State {counter: fromCounter.State;bookManage: fromBookManage.State; } export const reducers = {counter: fromCounter.reducer,bookManage: fromBookManage.reducer }; export const getExampleState = createFeatureSelector<State>('example'); // 計數器 export const getCounterState = createSelector(getExampleState, (state: State) => state.counter); export const getCounterCounter = createSelector(getCounterState, fromCounter.getCounter); // 圖書管理 export const getBookManageState = createSelector(getExampleState, (state: State) => state.bookManage); export const getBookManageList = createSelector(getBookManageState, fromBookManage.getList);

4、寫effect,檢測action類型,如果是search圖書行為,就發送網絡請求查結果(src/app/example/effects/book-manage.effect.ts)

import {Injectable} from '@angular/core'; import {Actions, Effect, ofType} from '@ngrx/effects'; import {Observable, of} from 'rxjs'; import {Action} from '@ngrx/store';import * as bookManage from '../actions/book-manage.actions'; import {BookManageService} from '../services/book-manage.service'; import {catchError, debounceTime, map, mergeMap, skip, takeUntil} from 'rxjs/operators'; import {BookResult} from '../model/book';@Injectable() export class BookManageEffects {@Effect()searchBook$: Observable<Action> = this.actions$.pipe(ofType(bookManage.SEARCH), // 判斷是不是搜索圖書的行為debounceTime(300), // 做延遲,節省網絡請求mergeMap((action: bookManage.SearchAction) => {const nextSearch$ = this.actions$.pipe(ofType(bookManage.SEARCH), skip(1));return this.service.searchBooks(action.payload).pipe(takeUntil(nextSearch$),// 如果搜索成功,發送成功action并且帶入搜索結果map((data: BookResult) => ({type: bookManage.SEARCH_COMPLETE, payload: data.items})),// 如果搜索失敗404之類的原因,發送成功action,以及空數組更新結果catchError(() => of({type: bookManage.SEARCH_COMPLETE, payload: []})));}));constructor(private actions$: Actions, private service: BookManageService) {} }

5、component獲取搜索結果和綁定搜索事件(src/app/example/containers/book-manage/book-manage.component.ts)

import { Component, OnInit } from '@angular/core'; import {Store} from '@ngrx/store'; import * as fromExample from '../../reducer'; import * as bookManageAction from '../../actions/book-manage.actions'; import {Observable} from 'rxjs'; import {Book} from '../../model/book'; @Component({selector: 'app-book-manage',templateUrl: './book-manage.component.html',styleUrls: ['./book-manage.component.css'] }) export class BookManageComponent implements OnInit {searchResult$: Observable<Book[]>; // 搜索到的圖書列表constructor(private store: Store<fromExample.State>) {// 從store中選取圖書搜索結果this.searchResult$ = this.store.select(fromExample.getBookManageList);}ngOnInit() {}// 發送搜索行為search(bookName) {this.store.dispatch(new bookManageAction.SearchAction(bookName));}}

頁面(src/app/example/containers/book-manage/book-manage.component.html)

<div class="container"><app-search-input (search)="search($event)"></app-search-input><app-book-list [bookList]="searchResult$ | async"></app-book-list> </div>

6、導入effect,否則會不起作用哦 (src/app/example/example.module.ts)

... import {BookManageEffects} from './effects/book-manage.effect'; import {EffectsModule} from '@ngrx/effects';@NgModule({...imports: [EffectsModule.forFeature([BookManageEffects]),],

ngrx 入門_霞霞的博客的博客-CSDN博客_ngrx文檔

總結

以上是生活随笔為你收集整理的ngrx学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。