基于前两篇文章的铺垫,这一篇文章就很轻松了。
不同框架下使用xstate
官方为 vue
和 react
都提供了对应版本的 xstate
,具体细节可以参看:
angular
没有官方版本,具体使用可以参考 在Angular中使用xstate。
使用原理
不管使用哪个框架,思路都大同小异:在状态机启动之后,监听 state
的改变,获取实时的 context
(上下文),然后映射到页面中。
在 angular
中,xstate
被当作服务引用,状态机在启动之后,我们通过 rxjs
将状态转变转化成 observable
对象,通过订阅去获取实时的 context
(上下文)。
// 启动状态机
private machineSrv = interpret(covidMachine, { devTools: true }).start();
// 将状态机的变化转变成 observable
state$: Observable<any> = from(this.machineSrv).pipe(
filter(state => state.changed)
);
总结:
- 启动状态机
- 监听状态机变化
组件联动
具体到某个组件想要使用状态机,则在组件相对应的生命钩子中引入启动后的状态机,获取 context
。
// app.component.ts
export class AppComponent {
countryData: any[];
countryList: any[];
state: any = {};
constructor(private covidSrc: CovidService) {
// 订阅状态机服务,获取上下文,然后赋值
this.covidSrc.state$.subscribe((covidState: any) => {
this.state = covidState;
const { countryRef, listCountries } = covidState.context;
this.countryList = listCountries ? listCountries : [];
this.countryData = countryRef
? this.processData(countryRef.state.context)
: [];
});
}
/** Helper */
processData(data: any) {
// 数据处理
}
}
赋值之后,把值映射到 html
中即可。
<p style="text-align:center" *ngIf="state.context">
{{ state.matches("idle") ? "Select a country" : null }}
</p>
<!-- 下拉框 -->
<app-select [data]="countryList" (selectChange)="selectCountry($event)"></app-select>
<!-- 数字卡片 -->
<app-number [data]="countryData"></app-number>
<!-- 条形图 -->
<app-bar [data]="countryData"></app-bar>
总结
我们拿到状态机,一般有两个作用:
拿到状态,用
state.match
匹配状态<!-- 如果状态机处于“idle”状态时的处理 --> {{ state.matches("idle") ? "Select a country" : null }}
拿到上下文(
context
),获取页面中需要的数据this.state = covidState; const { countryRef, listCountries } = covidState.context; this.countryList = listCountries ? listCountries : [];
至此,一个基于xstae的新冠动态追踪网页就搭建完成了,具体的细节打击可以参考线上Demo。
往期回顾:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。