Метод полезности для завершения интерпретатора Xstate и прочтения мета -информации состояния, чтобы ваш StateChart можно было использовать для создания дерева компонентов для рендеринга.
$ > npm install xstate-component-treeСоздайте Xstate StateChart, а затем создайте с ним интерпретатор Xstate.
const { Machine , interpret } = require ( "xstate" ) ;
const statechart = Machine ( {
initial : "one" ,
states : {
one : { } ,
} ,
} ) ;
const service = interpret ( statechart ) ; Добавьте meta -объекты в каждое состояние, которое вы хотите представить компонент.
Machine ( {
initial : "one" ,
states : {
one : {
meta : {
component : MyComponent ,
} ,
} ,
} ,
} ) ; Реквизиты для компонентов также поддерживаются через ключ props .
// ...
one : {
meta : {
component : MyComponent ,
props : {
prop1 : 1
} ,
} ,
} ,
// ...Затем передайте экземпляр интерпретатора и функцию обратного вызова в этот модуль!
const { Machine , interpret } = require ( "xstate" ) ;
const ComponentTree = require ( "xstate-component-tree" ) ;
const statechart = Machine ( {
// ...
} ) ;
const service = interpret ( statechart ) ;
new ComponentTree ( service , ( tree ) => {
// ...
} ) ; Второй аргумент для функции будет вызывать каждый раз, когда машина переходит. Он пройдет обратный вызов новый объект, представляющий все представления, определенные в активных в настоящее время государствах, все правильно вложенные в соответствии со структурой StateChart. Каждый элемент в ответе также будет содержать значение path , соответствующее конкретному состоянию, которое представляет объект.
new ComponentTree ( service , ( tree ) => {
/**
*
* tree will be something like this
*
* [{
* path : "one",
* component: MyComponent,
* children: [],
* props: false,
* }]
*
* or if there are nested components
*
* [{
* path : "one",
* component: MyComponent,
* props: false
* children : [{
* path : "one.two",
* component : ChildComponent,
* props: {
* one : 1
* },
* children: []
* }]
* }]
*
*/
} ) ; Эта структура данных также может содержать компоненты из любых детей, которые вы создали, используемые с использованием invoke , они будут правильно проходить и контролировать для переходов и появляться в их ожидаемом положении в иерархии. Это позволяет вам составлять более крупный StateChart из нескольких небольших и все еще заставляет их вносить вклад в приложение.
Вы можете динамически загружать компоненты или реквизиты, используя любую функциональность, которая вам нравится через клавишу load . Чтобы загрузить компоненты, асинхронно вернуть обещание или использовать async / await .
// ...
one : {
meta : {
load : ( ) => import ( "./my/component/from/here.js" ) ,
} ,
} ,
// ... Динамические реквизиты также поддерживаются. Чтобы вернуть реквизиты, возвращайте массив из load , где первое значение является компонентом, а второе - реквизит для компонента. Оба значения поддерживают возвращенное обещание.
// ...
one : {
meta : {
load : ( context ) => [
import ( "./my/component/from/here.js" ) ,
{
prop1 : context . prop1
} ,
] ,
} ,
} ,
// ... Функция load будет передана параметрам context и event от Xstate.
component помощник xstate-component-tree/component имеет именованный экспорт, называемый component , который является небольшой функцией для абстрагирования назначения meta объекту в каждом узле состояния, который нуждается в компоненте. Это удобная обертка, которая делает написание с xstate-component-tree немного чище.
import { component } from "xstate-component-tree/component";
// ...
- one : {
- meta: {
- component: OneComponent,
- },
- },
+ one : component(OneComponent), Установка реквизита для компонента обрабатывается путем передачи объекта с component и ключами props .
import { component } from "xstate-component-tree/component";
// ...
- one : {
- meta: {
- component : MyComponent,
- props : {
- prop1 : 1
- },
- },
- },
+ one : component({
+ component : OneComponent,
+ props : {
+ prop1 : 1,
+ },
+ }), Как component , так и клавиша props могут быть функцией, они будут переданы в одном и том же context и event , которые обычно передаются методам load() .
import { component } from "xstate-component-tree/component";
// ...
- one : {
- meta : {
- load : (context, event) => [
- import("./my/component/from/here.js"),
- {
- prop1 : context.prop1,
- },
- ],
- },
- },
+ one : component({
+ component : () => import("./my/component/from/here.js"),
+ props : (context) => ({
+ prop1 : context.prop1,
+ }),
+ }), ComponentTree new ComponentTree(interpreter, callback, [options])interpreter и экземпляр интерпретатора Xstatecallback , функция, которая будет выполняться каждый раз, когда готово новое дерево компонентовoptions , дополнительный объект, содержащий значения конфигурации для библиотеки. Функции callback получает два аргумента, первое - это ваше собравшееся дерево компонентов и реквизита. Второй - объект с некоторой полезной информацией на нем:
.state , возвращенный объект State Xstate для корневой машины.broadcast() , связанная версия API .broadcast() документированное ниже.can() , связанная версия API .can() задокументированное ниже.hasTag() , связанная версия API .hasTag() документированное ниже.matches() , связанная версия API .matches() документированное ниже options cache (по умолчанию true ), логическое определение, определяя, следует ли кэшировать значение load() или нет. Это может быть переопределено, установив meta.cache на любом состоянии в дереве, где кэширование должно быть отключено.
stable (по умолчанию: false ), сообщает библиотеке сортировать состояния в алфавитном порядке, прежде чем ходить по ним на каждом уровне, чтобы обеспечить, чтобы вывод компонента был более последовательным между переходами состояния.
verbose (по умолчанию: false ), регистрирует информацию о внутренних работах и решениях.
ComponentTree .broadcast(eventName | eventObject, payload) Вызывает метод xstate .send() на каждом запущенном переводчике в иерархии. Это особенно полезно, чтобы избежать использования опции autoforward на всех ваших вызываемых детских машинах.
eventName - это строковое событие, которое будет отправленоeventObject - это объект с свойством type имени события, а также другие дополнительные поляpayload - это объект дополнительных полей, которые будут добавлены в объект события .can(eventName | eventObject) Вызывает метод xstate .can() на каждом запущенном переводчике в иерархии.
eventName - это строковое событие, которое будет отправленоeventObject - это объект с свойством type имени события, а также другие дополнительные поля .hasTag(tag)tag - это строка, которая может быть определена на состояниях с использованием свойства tags Вызывает метод xstate .hasTag() против всех работающих машин и возвращает результат, останавливаясь на первом успешном матче.
.matches(stateName)stateName - это полное или частичное значение состояния, указанное как строка Вызывает метод xstate .matches() против всех работающих машин и возвращает результат, останавливаясь на первом успешном матче.
component() помощник component помощник возвращает узел xstate в качестве буквального объекта, он является исключительно удобным методом для авторов StateChart.
component(Component | () => {}, [node])Component является либо компонентом, либо функцией стрелки, которая будет выполнена. Он поддерживает функции, которые возвращают либо компонент, либо Promise .node -это действительный узел Xstate, meta объект будет создан и смешан с помощью component() . component({ component : Component | () => {}, props : {...} | () => {} })component является либо необработанным компонентом, либо функцией стрелки, которая будет выполнена. Он поддерживает возвращение либо стоимости, либо Promise .props - это либо объект реквизита, либо функция, которая будет выполнена. Он поддерживает функцию возврата либо значения, либо Promise . Как только у вас есть дерево компонентов, то, как вы собрали это в свой просмотр слой, полностью зависит от вас! Вот краткий пример.
{#each components as { path, component, props, children } (path)}
< svelte:component this = {component} {...props} {children} />
{/each}
< script >
export let components ;
</ script >