谈谈ngrx

关于ngrx

ngrx即为angular-redux,是redux基于angular封装的一个angular状态管理库,用于管理angular各个组件的状态。在angular中,也可以直接使用redux,但是angular-redux为我们的angular开发提供了很大的便利。
关于redux可参考我的这篇博客

若你对redux有了一定的了解,那么你应该察觉到redux嵌入react或者angular中使用时,在一些节点上还有不足之处,比如路由数据的管理,action和http请求顺序问题,连环的action处理问题,错误处理等等。而angular-redux,则为angular对这些问题作出处理。

打开google书城github上的例子,在readme.md介绍中,可以看到这么一段:

Included

  • ngrx/store - RxJS powered state management for Angular apps, inspired by Redux
  • ngrx/effects - Side effect model for @ngrx/store
  • angular/router - Angular Router
  • ngrx/db - RxJS powered IndexedDB for Angular apps
  • ngrx/store-devtools - Instrumentation for @ngrx/store enabling time-travel debugging
  • codewareio/ngrx-store-freeze - A @ngrx/store meta reducer that prevents state from being mutated
  • reselect - Selector library for Redux

这表明,ngrx除了使用ngrx/store封装了redux的基础功能外,还添加了ngrx/effects,ngrx/db等功能模块。

下面简单介绍一下这些模块的主要功能

store

angular的状态管理的核心模块,主要是将redux进行angular语法的封装。在angular中使用也很简单。见github上的ngrx/store的例子。

  • 在counter.ts中,先定义了一个reducer
import { Action } from '@ngrx/store';
...
export function counterReducer(state: number = 0, action: Action) {
    switch (action.type) {
        case INCREMENT:
        ...
    }
}
  • 使用StoreModule.provideStore(reducers),将其导入到根模块AppModule中,使根模块下的任何组件模块可使用它

    import { NgModule } from '@angular/core'
    import { StoreModule } from '@ngrx/store';
    import { counterReducer } from './counter';
    
    @NgModule({
    imports: [
        BrowserModule,
        StoreModule.forRoot({ count: counterReducer })
    ]
    })
    export class AppModule {}
    
  • 在组件中订阅使用这个reducer

    ...
    <div>Current Count: {{ count$ | async }}</div>
    ...
    constructor(private store: Store<AppState>) {
        this.count$ = store.pipe(select('count'));
    }
    

effects

该模块的主要作用是用于处理action的。
若你使用过了ngrx/store或者redux,那么你可能会考虑到这么一个状况:
当在ui视图上进行操作需要与服务器进行数据交互时,那么,这时应该先发送http请求还是先发生一个action呢?或者是发送http请求成功后再发出action?而有时候可能需求还不止这么简单,比如在发送http请求成功后又要发送另外的action,若这些逻辑操作都在ui层进行,毋庸置疑,组件中的代码是非常糟糕的。
若我们将http请求进行隔离,即UI层只负责展现和发起action,不用去考虑发起哪个http请求,这样对于我们的ui层岂不是更加的友好吗?
而对于发生什么http请求,则由我们的action来决定。而action后续的操作(http请求,数据筛选,错误处理,后续action等等)则是effects需要做的事情。
effects可以作这些复杂的操作,得益于rxjs的使用,而rxjs是一个基于可观察对象的数据流处理库。

router-store

在ngrx4.0最新版本中,加入了ngrx/router-store,将router进行store化管理。

ngrx/db

使用可观察对象(obseveber)对localstorage操作进行封装。

store-devtools

使用angular对redux-devtools进行封装,用于store状态的可视化。

reselect

用于从store中读取数据。

最后

以上每一项拿出来都可以写一大篇的博客,具体ngrx的原理不是一篇博客就能说的清的,要深入学习ngrx有很高的门槛,除了学会使用angular以外,还要学习redux,rxjs,typescript,reselect等等。而光是rxjs,就是一个高抽象的,不易学习的技术。前端之路,遥遥无期。。