Xstate:导致相同状态的不同动作和守卫
Xstate: different actions and guards leading to same state
我正在使用 xstate 库编写状态图。
状态图表示中等复杂度UI。
我有几个并行状态,但对于这个问题,我们只考虑两个:
SelectionStatus
,表示 select 项,区分子状态 SelectedNone
、SelectedOne
、SelectedMany
.
Operation
,表示当前正在进行的操作。它有一个名为 Idle
的子状态(当然还有其他一些)。
有一些事件会触发循环回到 Idle
子状态的动作,而不会转到另一个状态。让我们将它们视为即时操作,例如 removeSelected
操作仅删除 selected 项目(这就是问题的重点)。
我正在向事件 removeSelected
添加条件以在 selection 仅限于单个项目(实际上是树中的一个节点)或多个(一个分支的分支)时执行不同的操作树)。
描述事件的动作和条件的 xstate 语法将是:
removeSelected: {
Idle: {
cond: isSelectedOneGuard,
actions: ['removeOne']
},
Idle: {
cond: isSelectedManyGuard,
actions: ['removeMany']
}
}
问题是我在相同的对象嵌套级别写了两个 Idle
键,这是无效的。
我考虑过重组状态图,将两个操作分支作为 selection 的子状态,但它似乎比问题更糟糕。
我也考虑过使用像 RemovingOne
和 RemovingMany
这样的中间虚拟状态,这只会触发返回到 Idle
的转换,但我对此不太满意。
我可以通过删除保护条件来解决这个问题,在通用 removeOneOrMany
操作处理程序中进行测试,但我会在状态图中丢失有关不同处理的信息。
有人遇到过类似的问题,可以提供一些建议吗?
(注:这里指的是xstate的当前版本,3.1.1,3.2也差不多了,不知道能不能更方便地处理这种情况)
谢谢!
使用当前语法 (3.1),您可以将不同的 "candidate transitions" 放入一个数组中:
removeSelected: [
{
target: 'Idle',
cond: isSelectedOneGuard,
actions: ['removeOne']
},
{
target: 'Idle',
cond: isSelectedManyGuard,
actions: ['removeMany']
}
]
我正在使用 xstate 库编写状态图。
状态图表示中等复杂度UI。
我有几个并行状态,但对于这个问题,我们只考虑两个:
SelectionStatus
,表示 select 项,区分子状态 SelectedNone
、SelectedOne
、SelectedMany
.
Operation
,表示当前正在进行的操作。它有一个名为 Idle
的子状态(当然还有其他一些)。
有一些事件会触发循环回到 Idle
子状态的动作,而不会转到另一个状态。让我们将它们视为即时操作,例如 removeSelected
操作仅删除 selected 项目(这就是问题的重点)。
我正在向事件 removeSelected
添加条件以在 selection 仅限于单个项目(实际上是树中的一个节点)或多个(一个分支的分支)时执行不同的操作树)。
描述事件的动作和条件的 xstate 语法将是:
removeSelected: {
Idle: {
cond: isSelectedOneGuard,
actions: ['removeOne']
},
Idle: {
cond: isSelectedManyGuard,
actions: ['removeMany']
}
}
问题是我在相同的对象嵌套级别写了两个 Idle
键,这是无效的。
我考虑过重组状态图,将两个操作分支作为 selection 的子状态,但它似乎比问题更糟糕。
我也考虑过使用像 RemovingOne
和 RemovingMany
这样的中间虚拟状态,这只会触发返回到 Idle
的转换,但我对此不太满意。
我可以通过删除保护条件来解决这个问题,在通用 removeOneOrMany
操作处理程序中进行测试,但我会在状态图中丢失有关不同处理的信息。
有人遇到过类似的问题,可以提供一些建议吗?
(注:这里指的是xstate的当前版本,3.1.1,3.2也差不多了,不知道能不能更方便地处理这种情况)
谢谢!
使用当前语法 (3.1),您可以将不同的 "candidate transitions" 放入一个数组中:
removeSelected: [
{
target: 'Idle',
cond: isSelectedOneGuard,
actions: ['removeOne']
},
{
target: 'Idle',
cond: isSelectedManyGuard,
actions: ['removeMany']
}
]