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']
  }
]
Другие вопросы по тегам