1.Ngxs

在介绍Ngxs之前我们先来了解一下另外一个在Angular项目中用于做状态管理的解决方案;Ngrx,Ngrx的设计灵感来源于Redux,并且使用Rxjs来实现.但是由于Ngrx过于臃肿,在本就庞大的Angular中引入这么一套方案,确实不是很合理,所以就有人在Ngrx的基础上做了减法,诞生了Ngxs.
这里就不过多解释为什么需要使用状态管理.只是针对我们在使用Ngxs的过程中异步的问题和解决方案.

2.Ngxs核心概念

  • Store: 全局状态容器,操作调度程序和选择器
  • Actions: 描述要采取的操作及其关联元数据的类
  • State: 状态的类定义
  • Selects: 状态选择器

upload successful

这里也有一个很简单的demo,基本上看一遍就能很快的清楚Ngxs的实现原理
https://stackblitz.com/edit/ngxs-simple

3.Ngxs使用

  1. 定义接口数据类型
interface  Book {
name:string,//名称
intro:string,//简介
category:number,//类别
}

enum category {
autobiography=1,
novel=2,
tool=3,
other=4,
}
  1. 定义model数据类型
interface BookModel {
bookList: Book[],
count: number,
}
  1. 定义action和state
class Addbook {
static readonly type = 'addbook';
constructor(public params: Books) { }
}

class GetBookList{
static readonly type = 'getBookList';
constructor(){}
}
@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');
}
}
}
  1. 组件中调用action
  • 添加图书
@Component({...})
export class AppComponent {

constructor(){
const newBook={
name:'十万个为什么',
intro:'儿童读物',
category:4,
}

this.store.dispatch(new Addbook(newBook))
.subscribe(
r => {
//请求成功,
},
e=>{
//请求失败
});
}
}
  • 获取图书列表
@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

  • Snapshot
    可以从store中获取原始值
const snapshot = this.store.selectSnapshot(state => state.book.bookList)  //[]
  • Memoized
    根据自定义条件选组合适的数据
export class BooksState{
@Selector()
static novels(state:BookModel) {
return state.bookList.filter(e => e.category===1);
}
}
@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的一款插件来协助开发,提升开发效率

npm install @ ngxs / devtools-plugin --save-dev 

#yarn
yarn add @ ngxs / devtools-plugin --dev
import { NgxsReduxDevtoolsPluginModule } from '@ngxs/devtools-plugin';

@NgModule({
imports: [
NgxsReduxDevtoolsPluginModule.forRoot()
]
})
export class AppModule {}