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使用
- 定义接口数据类型
| 12
 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数据类型
| 12
 3
 4
 
 | interface BookModel {bookList: Book[],
 count: number,
 }
 
 | 
- 定义action和state
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | class Addbook {static readonly type = 'addbook';
 constructor(public params: Books) { }
 }
 
 class GetBookList{
 static readonly type = 'getBookList';
 constructor(){}
 }
 
 | 
| 12
 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
| 12
 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=>{
 //请求失败
 });
 }
 }
 
 
 
 
 | 
| 12
 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)  //[]
 | 
| 12
 3
 4
 5
 6
 7
 
 | export class BooksState{@Selector()
 static novels(state:BookModel) {
 return state.bookList.filter(e => e.category===1);
 }
 }
 
 
 | 
| 12
 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的一款插件来协助开发,提升开发效率
| 12
 3
 4
 
 | npm install @ ngxs / devtools-plugin --save-dev 
 #yarn
 yarn add @ ngxs / devtools-plugin --dev
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 
 | import { NgxsReduxDevtoolsPluginModule } from '@ngxs/devtools-plugin';
 @NgModule({
 imports: [
 NgxsReduxDevtoolsPluginModule.forRoot()
 ]
 })
 export class AppModule {}
 
 |