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

Posted

技术标签:

【中文标题】Xstate:导致相同状态的不同动作和守卫【英文标题】:Xstate: different actions and guards leading to same state 【发布时间】:2018-09-21 13:22:56 【问题描述】:

我正在用 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】:

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

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

【讨论】:

以上是关于Xstate:导致相同状态的不同动作和守卫的主要内容,如果未能解决你的问题,请参考以下文章

使用 xstate,是不是可以配置一个适用于所有状态并在所有状态和子状态中以相同方式处理的事件?

有限马尔可夫决策过程

帮助我更好地理解 Struts2、验证和有状态操作

xstate中的嵌套属性分配?

路网路径规划中q_learning动作集如何设计

热敏电阻主要作用是啥?