Xstate:导致同一状态的不同动作和守卫

时间:2018-04-11 15:15:36

标签: statechart xstate

我正在用xstate库编写状态图表。

状态图表示中等复杂的UI。

我有几个平行状态,但对于这个问题,我们只考虑两个:

SelectionStatus,代表选择项,区分子状态SelectedNoneSelectedOneSelectedMany

Operation,表示当前正在进行的操作。它有一个名为Idle的子状态(当然还有其他一些子状态)。

有些事件会触发循环回Idle子状态的操作,而不会转到另一个状态。让我们将它们视为即时动作,例如removeSelected动作只删除所选项目(并且问题的关键点)。

如果选择仅限于单个项目(实际上是树中的节点)或许多(树的一个分支),我正在向事件removeSelected添加条件以执行不同的操作。

用于描述事件的操作和条件的xstate的语法将是:

removeSelected: {
    Idle: {
         cond: isSelectedOneGuard,
         actions: ['removeOne']
    },
    Idle: {
         cond: isSelectedManyGuard,
         actions: ['removeMany']
    }
}

问题是我在相同的对象嵌套级别写了两个Idle个键,这是无效的。

我已经考虑重组状态图,将两个操作分支作为选择的子类,但似乎治愈的程度远远超过问题。

我还考虑使用像RemovingOneRemovingMany这样的中间虚拟状态,它们只会触发转换回Idle,但我对此并不满意。

我可以通过删除保护条件来解决这个问题,在通用removeOneOrMany动作处理程序中进行测试,但是我会在状态图中忽略有关不同处理的信息。

任何人都有类似的问题,可以就此提出一些建议吗?

(注意:这是指当前版本的xstate,它是3.1.1,3.2几乎就在那里,我不知道它是否允许更容易处理这种情况)

谢谢!

1 个答案:

答案 0 :(得分:3)

使用当前语法(3.1),您可以将不同的"候选转换"在数组中:

removeSelected: [
  {
    target: 'Idle',
    cond: isSelectedOneGuard,
    actions: ['removeOne']
  },
  {
    target: 'Idle',
    cond: isSelectedManyGuard,
    actions: ['removeMany']
  }
]