1.Ngxs
在介绍Ngxs之前我们先来了解一下另外一个在Angular项目中用于做状态管理的解决方案;Ngrx,Ngrx的设计灵感来源于Redux,并且使用Rxjs来实现.但是由于Ngrx过于臃肿,在本就庞大的Angular中引入这么一套方案,确实不是很合理,所以就有人在Ngrx的基础上做了减法,诞生了Ngxs.
这里就不过多解释为什么需要使用状态管理.只是针对我们在使用Ngxs的过程中异步的问题和解决方案.
2.Ngxs核心概念
- Store: 全局状态容器,操作调度程序和选择器
- Actions: 描述要采取的操作及其关联元数据的类
- State: 状态的类定义
- Selects: 状态选择器

这里也有一个很简单的demo,基本上看一遍就能很快的清楚Ngxs的实现原理
https://stackblitz.com/edit/ngxs-simple
3.Ngxs使用
- 定义接口数据类型
1 2 3 4 5 6 7 8 9 10 11 12
| interface Book { name:string,//名称 intro:string,//简介 category:number,//类别 }
enum category { autobiography=1, novel=2, tool=3, other=4, }
|
- 定义model数据类型
1 2 3 4
| interface BookModel { bookList: Book[], count: number, }
|
- 定义action和state
1 2 3 4 5 6 7 8 9
| class Addbook { static readonly type = 'addbook'; constructor(public params: Books) { } }
class GetBookList{ static readonly type = 'getBookList'; constructor(){} }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| @State<BookModel>({ name: 'book', //名称,确保唯一 defaults: { //默认值 bookList: [], count: 0, }, })
export class BooksState{ @Action(Addbook) async addBook(context:StateContext<BookModel>,action:Addbook){ try{ let addBook=await Promise addBook(action.params); //获取当前最新的值 const state = context.getState(); const books = [...state.bookList, addBook];
//请求成功 context.patchState({ bookList: bookList, count: state.count+1 }) }catch(error){ //请求失败 throw new Error('error'); } } @Action(GetBookList) async getBookList(context:StateContext<BookModel>,action:GetBookList){ try{ const { result , count } =await Promise getBookList(action.params); //请求成功 context.patchState({ bookList: result, count: count }) }catch(error){ //请求失败 throw new Error('error'); } } }
|
- 组件中调用action
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @Component({...}) export class AppComponent {
constructor(){ const newBook={ name:'十万个为什么', intro:'儿童读物', category:4, } this.store.dispatch(new Addbook(newBook)) .subscribe( r => { //请求成功, }, e=>{ //请求失败 }); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Component({...}) export class AppComponent {
@Select(BooksState) bookList$: Observable<Array<Book>>;
//or bookList$: Observable<Array<Book>>; constructor(private store: Store){ this.bookList$=this.store.select(state=>state.book.bookList); } }
|
补充select
1
| const snapshot = this.store.selectSnapshot(state => state.book.bookList) //[]
|
1 2 3 4 5 6 7
| export class BooksState{ @Selector() static novels(state:BookModel) { return state.bookList.filter(e => e.category===1); } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| @Component({...}) export class AppComponent { @Select(BooksState.novels) novels$: Observable<Array<Book>; //or novels$: Observable<Array<Book>> constructor(private store: Store) { this.novels$ = this.store.select(BooksState.novels); } }
|
2. 这里可以使用Redux的一款插件来协助开发,提升开发效率
1 2 3 4
| npm install @ ngxs / devtools-plugin --save-dev
#yarn yarn add @ ngxs / devtools-plugin --dev
|
1 2 3 4 5 6 7 8
| import { NgxsReduxDevtoolsPluginModule } from '@ngxs/devtools-plugin';
@NgModule({ imports: [ NgxsReduxDevtoolsPluginModule.forRoot() ] }) export class AppModule {}
|