angular 定义对象_Angular状态管理框架NgRx入门

ngrx概念

  • 一个框架
  • 用于构建Angular8响应式应用
  • 用于状态管理
  • 使用可观察对象
  • 使用Typescript
  • 使用OnPush策略,变更检测更高效
  • 状态序列化存储
  • 易于测试

原理图

eb71ead809c38447b147b824a15ffd12.png
  • component产生action(事件)
  • action触发effect,业务处理数据
  • store中存储state、reducer
  • reducer产生新的state
  • state修改,更新component

简单入门

初始化项目

ng new ngrx-demo
> ng new ngrx-demo ? Would you like to add Angular routing? Yes? Which stylesheet format would you like to use? SCSS [ https://sass-lang.com/documentation/syntax#scss ]CREATE ngrx-demo/README.md (1026 bytes)CREATE ngrx-demo/.editorconfig (246 bytes)CREATE ngrx-demo/.gitignore (631 bytes)CREATE ngrx-demo/angular.json (3705 bytes)CREATE ngrx-demo/package.json (1295 bytes)CREATE ngrx-demo/tsconfig.json (543 bytes)CREATE ngrx-demo/tslint.json (1953 bytes)CREATE ngrx-demo/browserslist (429 bytes)CREATE ngrx-demo/karma.conf.js (1021 bytes)CREATE ngrx-demo/tsconfig.app.json (270 bytes)CREATE ngrx-demo/tsconfig.spec.json (270 bytes)CREATE ngrx-demo/src/favicon.ico (948 bytes)CREATE ngrx-demo/src/index.html (294 bytes)CREATE ngrx-demo/src/main.ts (372 bytes)....added 1461 packages from 1071 contributors in 85.831s Successfully initialized git.

安装ngrx

npm install @ngrx/store --save

创建Angular组件my-counter

ng generate @schematics/angular:component my-counter --style=scss <

定义action

//app/counter.actions.tsimport { createAction } from '@ngrx/store';export const increment = createAction('[Counter Component] Increment');export const decrement = createAction('[Counter Component] Decrement');export const reset = createAction('[Counter Component] Reset');

定义reducer初始状态为数值

//app/counter.reducer.tsimport { createReducer, on } from '@ngrx/store';import { increment, decrement, reset } from './counter.actions';export const initialState = 0;const _counterReducer = createReducer(initialState, on(increment, state => state + 1), on(decrement, state => state - 1), on(reset, state => 0),);export function counterReducer(state, action) { return _counterReducer(state, action);}

注册state

import { BrowserModule } from '@angular/platform-browser';import { NgModule } from '@angular/core';import { AppComponent } from './app.component';import { StoreModule } from '@ngrx/store';import { counterReducer } from './counter.reducer';@NgModule({ declarations: [AppComponent], imports: [ BrowserModule, StoreModule.forRoot({ count: counterReducer }) // 注册时指定key ], providers: [], bootstrap: [AppComponent],})export class AppModule {}

定义组件

# app / my-counter / my-counter.component.html
Increment
Current Count: {{ count$ | async }}
DecrementReset Counter

组件触发action

# app / my-counter / my-counter.component.ts
import { Component } from '@angular/core';import { Store, select } from '@ngrx/store';import { Observable } from 'rxjs';import { increment, decrement, reset } from '../counter.actions';@Component({ selector: 'app-my-counter', templateUrl: './my-counter.component.html', styleUrls: ['./my-counter.component.css'],})export class MyCounterComponent { count$: Observable; constructor(private store: Store) { this.count$ = store.pipe(select('count')); //这里关键点,在于app.module.ts注册时候的key } increment() { this.store.dispatch(increment()); } decrement() { this.store.dispatch(decrement()); } reset() { this.store.dispatch(reset()); }}

组件生效

// app.component.html 
this is app component
//界面按钮点击,观测数据变化

store.pipe写法解惑

//查看store源码,我们得到Observable export declare class Store extends Observable implements Observer { ....}

store.select也是Observable

export declare function select(mapFn: (state: T, props: Props) => K, props?: Props): (source$: Observable) => Observable;
this.store .select(fromStore.getProductsState) .map(state => state.pizzas) .map(pizzas => pizza.entities);

进阶

当reducer初始状态state为对象时

//counter.reducer.tsimport { createReducer, on } from '@ngrx/store';import { increment, decrement, reset } from './counter.actions';export interface State { away: number;}export const initialState: State = {  away: 0,};const _counterReducer = createReducer(initialState, on(increment, state => ({...state, away: state.away + 1})), on(decrement, state => ({...state, away: state.away - 1})), on(reset, state => ({...state, away: 0})),);export function counterReducer(state, action) { return _counterReducer(state, action);}

延迟加载state注册

# 新增文件app/feature.module.tsimport { NgModule } from '@angular/core';import { StoreModule } from '@ngrx/store';import { counterReducer } from './counter.reducer';@NgModule({ imports: [ StoreModule.forFeature('countFeture', counterReducer) # 需要注意,对应的调整 ],})export class ScoreboardModule {}
import { BrowserModule } from '@angular/platform-browser';import { NgModule } from '@angular/core';import { AppRoutingModule } from './app-routing.module';import { AppComponent } from './app.component';import { StoreModule } from '@ngrx/store';import { counterReducer } from './counter.reducer';import { MyCounterComponent } from './my-counter/my-counter.component';import { ScoreboardModule } from './feature.module';@NgModule({ declarations: [ AppComponent, MyCounterComponent ], imports: [ BrowserModule, AppRoutingModule, StoreModule.forRoot({}), ScoreboardModule ], providers: [], bootstrap: [AppComponent]})export class AppModule { }

参考文献:

  • ngrx.io/guide/store

本文作者:前端首席体验师(CheongHu)

联系邮箱:simple2012hcz@126.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值