xstate
官网上有个用例,使用 xstate+react
实现了一个 covid tracker
,能够实时展示某个国家(地区)的新冠动态,于是复刻一个 angular
的版本,也算是一个学习和提高的过程,最终实现的效果如下图:
项目并不复杂( UI
比逻辑更耗时),但是能够加深对 xstae
中 actor
模式的理解,以及 invoke
的使用。
考虑到如果把文章内容都整合到一起,长长的滚动条会让人望而却步,因此文章将分为三个篇幅进行讲解:
- 项目搭建:完成页面的基础部分
- 实现状态机:完成转态机的代码
- 综合运用:将状态机运用到具体的组件中
篇幅都不长,图文并茂,可随到随看,希望能给大家带来启发。
初始化项目
开发工具
这里直接选择了线上开发,使用了 stackblitz
(微软)的脚手架工具创建了 angular
工程目录。
比较出名的线上开发网站还有 codesandbox
,现在比较多人使用,速度快,也不用翻墙。
目录结构
无论用vue
还是react
或者angular
,都建议单独创建一个machine
目录用于存放状态机,方便维护和管理。
本项目使用angular
,所以要采用服务的方式使用xstate
,除了machine
目录,还需要有一个services
目录存放解析状态机后的服务。
更多细节可以前往 在Angular中使用xstate
目录结构如图:
这里有几个要点:
component
不直接操作machine
,通过services
转换之后引入。- 为什么会有两个
machine
文件?因为我们要使用
actor
特性,covidMachine
用于存储所有的资料,他的context
中会有一个countryRef
属性,指向当前选中的国家。而这个countryRef
,正是通过孵化(spawn
)产生的actor
,这个actor
,就是covidDataMachine
!
搭建页面
项目中只有一个入口页面app.component.ts
,和三个组件:
bar.component.ts
:条形图number.component.ts
:统计卡select.component.ts
:页面中能够交互的唯一组件,下拉框。展示所有国家和监听用户的选择。
项目中使用了 ngx-charts
图表组件
页面一览:
//app.component.ts
import { Component } from "@angular/core";
@Component({
selector: "my-app",
styles: [
`
:host {
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
`
],
template: `
<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>
`
})
export class AppComponent {
countryData: any[];
countryList: any[];
state: any = {};
selectCountry(name: string) {
// TODO:
}
}
页面也比较简单,有几个要点:
- 数据的更改处理尽量在父组件中完成,子组件只负责展示数据以及发送事件
相关字段的注释:
countryData
:存放当前country
的数据countryList
:存放所有country
的信息(名称)state
:状态机
搭建页面并非 xstate
的内容,这里就不做展开了。
下一章我们将实现状态机。点击跳转:
线上Demo
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。