Xstate: различные действия и охранники, ведущие к одному и тому же состоянию
Я пишу диаграмму состояний с помощью библиотеки xstate.
Диаграмма состояний представляет собой интерфейс среднего уровня сложности.
У меня есть несколько параллельных состояний, но для этих вопросов давайте учтем только два:
SelectionStatus
, который представляет элемент (ы) выбора, различая подсостояния SelectedNone
, SelectedOne
, SelectedMany
,
Operation
, который представляет текущую операцию в процессе. У этого есть подсостояние под названием Idle
(среди прочего, конечно).
Есть некоторые события, которые запускают действия, которые возвращаются к Idle
субстрат, не переходя в другое государство. Давайте подумаем о них как о немедленных действиях, например removeSelected
действие, которое просто удаляет выбранный элемент (ы) (и в этом суть вопроса).
Я добавляю условия к событию removeSelected
выполнять различные действия, если выбор ограничен одним элементом (фактически, узлом в дереве) или многими (ветвь дерева).
Синтаксис xstate для описания действий и условий для события будет таким:
removeSelected: {
Idle: {
cond: isSelectedOneGuard,
actions: ['removeOne']
},
Idle: {
cond: isSelectedManyGuard,
actions: ['removeMany']
}
}
Проблема в том, что я пишу два Idle
ключи на том же уровне вложенности объектов, что недопустимо.
Я рассматривал реструктуризацию диаграммы состояний, чтобы иметь две ветви операций в качестве подсостояний из выбранных, но это кажется гораздо более серьезным решением, чем проблема.
Я также подумал об использовании промежуточных пустых состояний, таких как RemovingOne
а также RemovingMany
который просто вызовет переход обратно к Idle
Но я не очень доволен этим.
Я мог бы решить эту проблему, сняв условие охраны, сделать тест в общем removeOneOrMany
обработчик действия, но я бы потерял информацию о другой обработке в диаграмме состояний.
У кого-нибудь была похожая проблема, и можете ли дать какое-то предложение по этому поводу?
(Примечание: это относится к текущей версии xstate, которая является 3.1.1, 3.2 почти готова, и я не знаю, может ли она разрешить этот случай проще)
Спасибо!
1 ответ
С текущим синтаксисом (3.1) вы можете поместить различные "переходы-кандидаты" в массив:
removeSelected: [
{
target: 'Idle',
cond: isSelectedOneGuard,
actions: ['removeOne']
},
{
target: 'Idle',
cond: isSelectedManyGuard,
actions: ['removeMany']
}
]