Skip to main content

GroupNode

Defined in: core/nodes/group-node.ts:81

GroupNode - узел для группы полей

Поддерживает два API:

  1. Старый API (только schema) - обратная совместимость
  2. Новый API (config с form, behavior, validation) - автоматическое применение схем

Example

// 1. Старый способ (обратная совместимость)
const simpleForm = new GroupNode({
email: { value: '', component: Input },
password: { value: '', component: Input },
});

// 2. Новый способ (с behavior и validation схемами)
const fullForm = new GroupNode({
form: {
email: { value: '', component: Input },
password: { value: '', component: Input },
},
behavior: (path) => {
computeFrom(path.email, [path.email], (values) => values[0]?.trim());
},
validation: (path) => {
required(path.email, { message: 'Email обязателен' });
email(path.email);
required(path.password);
minLength(path.password, 8);
},
});

// Прямой доступ к полям через Proxy
fullForm.email.setValue('test@mail.com');
await fullForm.validate();
console.log(fullForm.valid.value); // true

Extends

Type Parameters

T

T

Accessors

fields

Get Signature

get fields(): Map<keyof T, FormNode<FormValue>>;

Defined in: core/nodes/group-node.ts:384

Получить Map всех полей формы (для совместимости)

Returns

Map<keyof T, FormNode<FormValue>>

Constructors

Constructor

new GroupNode<T>(schema): GroupNode<T>;

Defined in: core/nodes/group-node.ts:165

Создать GroupNode только со схемой формы (обратная совместимость)

Parameters

schema

FormSchema<T>

Returns

GroupNode<T>

Overrides

FormNode.constructor

Constructor

new GroupNode<T>(config): GroupNode<T>;

Defined in: core/nodes/group-node.ts:170

Создать GroupNode с полной конфигурацией (form, behavior, validation)

Parameters

config

GroupNodeConfig<T>

Returns

GroupNode<T>

Overrides

FormNode<T>.constructor

Methods

applyBehaviorSchema()

applyBehaviorSchema(schemaFn): () => void;

Defined in: core/nodes/group-node.ts:506

Применить behavior schema к форме

Parameters

schemaFn

BehaviorSchemaFn<T>

Returns

Функция cleanup для отписки от всех behaviors

() => void


applyContextualValidators()

applyContextualValidators(validators): Promise<void>;

Defined in: core/nodes/group-node.ts:606

Применить contextual валидаторы к полям

✅ РЕФАКТОРИНГ: Делегирование ValidationApplicator (SRP)

Логика применения валидаторов извлечена в ValidationApplicator для:

  • Соблюдения Single Responsibility Principle
  • Уменьшения размера GroupNode (~120 строк)
  • Улучшения тестируемости

Parameters

validators

ValidatorRegistration[]

Зарегистрированные валидаторы

Returns

Promise<void>


applyValidationSchema()

applyValidationSchema(schemaFn): void;

Defined in: core/nodes/group-node.ts:487

Применить validation schema к форме

Использует локальный реестр валидаторов (this.validationRegistry) вместо глобального Singleton для изоляции форм друг от друга.

Parameters

schemaFn

ValidationSchemaFn<T>

Returns

void


clearErrors()

clearErrors(): void;

Defined in: core/nodes/group-node.ts:368

Очистить все errors (form-level + field-level)

Returns

void

Overrides

FormNode.clearErrors


disable()

disable(): void;

Defined in: core/nodes/form-node.ts:370

Отключить узел

Template Method: обновляет статус в базовом классе, вызывает hook для кастомной логики в наследниках

Отключенные узлы не проходят валидацию и не включаются в getValue()

Returns

void

Inherited from

FormNode.disable


dispose()

dispose(): void;

Defined in: core/nodes/group-node.ts:734

Очистить все ресурсы узла

Returns

void

Overrides

FormNode.dispose


enable()

enable(): void;

Defined in: core/nodes/form-node.ts:381

Включить узел

Template Method: обновляет статус в базовом классе, вызывает hook для кастомной логики в наследниках

Returns

void

Inherited from

FormNode.enable


getAllFields()

getAllFields(): IterableIterator<FormNode<FormValue>>;

Defined in: core/nodes/group-node.ts:425

Получить все поля формы как итератор

Returns

IterableIterator<FormNode<FormValue>>


getErrors()

getErrors(options?): ValidationError[];

Defined in: core/nodes/form-node.ts:231

Получить ошибки валидации с фильтрацией

Позволяет фильтровать ошибки по различным критериям:

  • По коду ошибки
  • По сообщению (частичное совпадение)
  • По параметрам
  • Через кастомный предикат

Без параметров возвращает все ошибки (эквивалент errors.value)

Parameters

options?

ErrorFilterOptions

Опции фильтрации ошибок

Returns

ValidationError[]

Отфильтрованный массив ошибок валидации

Example

// Все ошибки
const allErrors = form.getErrors();

// Ошибки с конкретным кодом
const requiredErrors = form.getErrors({ code: 'required' });

// Ошибки с несколькими кодами
const errors = form.getErrors({ code: ['required', 'email'] });

// Ошибки по сообщению
const passwordErrors = form.getErrors({ message: 'Password' });

// Ошибки по параметрам
const minLengthErrors = form.getErrors({
params: { minLength: 8 }
});

// Кастомная фильтрация
const customErrors = form.getErrors({
predicate: (err) => err.code.startsWith('custom_')
});

Inherited from

FormNode.getErrors


getField()

getField<K>(key): FormNode<T[K]> | undefined;

Defined in: core/nodes/group-node.ts:376

Получить поле по ключу

Type Parameters

K

K extends string | number | symbol

Parameters

key

K

Returns

FormNode<T[K]> | undefined


getFieldByPath()

getFieldByPath(path): 
| FormNode<FormValue>
| undefined;

Defined in: core/nodes/group-node.ts:549

Получить вложенное поле по пути

Поддерживаемые форматы путей:

  • Simple: "email" - получить поле верхнего уровня
  • Nested: "address.city" - получить вложенное поле
  • Array index: "items[0]" - получить элемент массива по индексу
  • Combined: "items[0].name" - получить поле элемента массива

Parameters

path

string

Путь к полю

Returns

| FormNode<FormValue> | undefined

FormNode если найдено, undefined если путь не существует

Example

const form = new GroupNode({
email: { value: '', component: Input },
address: {
city: { value: '', component: Input }
},
items: [{ name: { value: '', component: Input } }]
});

form.getFieldByPath('email'); // FieldNode
form.getFieldByPath('address.city'); // FieldNode
form.getFieldByPath('items[0]'); // GroupNode
form.getFieldByPath('items[0].name'); // FieldNode
form.getFieldByPath('invalid.path'); // undefined

getProxy()

getProxy(): any;

Defined in: core/nodes/group-node.ts:414

Получить Proxy-инстанс для прямого доступа к полям

Proxy позволяет обращаться к полям формы напрямую через точечную нотацию:

  • form.email вместо form.fields.get('email')
  • form.address.city вместо form.fields.get('address').fields.get('city')

Используется в:

  • BehaviorApplicator для доступа к полям в behavior functions
  • ValidationApplicator для доступа к форме в tree validators

Returns

any

Proxy-инстанс с типобезопасным доступом к полям или сама форма, если proxy не доступен

Example

const form = new GroupNode({
controls: {
email: new FieldNode({ value: '' }),
name: new FieldNode({ value: '' })
}
});

const proxy = form.getProxy();
console.log(proxy.email.value); // Прямой доступ к полю

getValue()

getValue(): T;

Defined in: core/nodes/group-node.ts:268

Получить значение узла (non-reactive) Использует .peek() для получения значения без создания зависимости

Returns

T

Overrides

FormNode.getValue


linkFields()

linkFields<K1, K2>(
sourceKey,
targetKey,
transform?): () => void;

Defined in: core/nodes/group-node.ts:642

Связывает два поля: при изменении source автоматически обновляется target

Type Parameters

K1

K1 extends string | number | symbol

K2

K2 extends string | number | symbol

Parameters

sourceKey

K1

targetKey

K2

transform?

(value) => T[K2]

Returns

() => void


markAsDirty()

markAsDirty(): void;

Defined in: core/nodes/form-node.ts:313

Отметить узел как dirty (значение изменено)

Template Method: обновляет signal в базовом классе, вызывает hook для кастомной логики в наследниках

Returns

void

Inherited from

FormNode.markAsDirty


markAsPristine()

markAsPristine(): void;

Defined in: core/nodes/form-node.ts:324

Отметить узел как pristine (значение не изменено)

Template Method: обновляет signal в базовом классе, вызывает hook для кастомной логики в наследниках

Returns

void

Inherited from

FormNode.markAsPristine


markAsTouched()

markAsTouched(): void;

Defined in: core/nodes/form-node.ts:291

Отметить узел как touched (пользователь взаимодействовал)

Template Method: обновляет signal в базовом классе, вызывает hook для кастомной логики в наследниках

Returns

void

Inherited from

FormNode.markAsTouched


markAsUntouched()

markAsUntouched(): void;

Defined in: core/nodes/form-node.ts:302

Отметить узел как untouched

Template Method: обновляет signal в базовом классе, вызывает hook для кастомной логики в наследниках

Returns

void

Inherited from

FormNode.markAsUntouched


onDisable()

protected onDisable(): void;

Defined in: core/nodes/group-node.ts:718

Hook: вызывается после disable()

Returns

void

Overrides

FormNode.onDisable


onEnable()

protected onEnable(): void;

Defined in: core/nodes/group-node.ts:726

Hook: вызывается после enable()

Returns

void

Overrides

FormNode.onEnable


onMarkAsDirty()

protected onMarkAsDirty(): void;

Defined in: core/nodes/group-node.ts:441

Hook: вызывается после markAsDirty()

Переопределите в наследниках для дополнительной логики:

  • GroupNode: может обновить родительскую форму
  • ArrayNode: может обновить родительскую форму
  • FieldNode: пустая реализация

Returns

void

Overrides

FormNode.onMarkAsDirty


onMarkAsPristine()

protected onMarkAsPristine(): void;

Defined in: core/nodes/group-node.ts:445

Hook: вызывается после markAsPristine()

Переопределите в наследниках для дополнительной логики:

  • GroupNode: пометить все дочерние узлы как pristine
  • ArrayNode: пометить все элементы массива как pristine
  • FieldNode: пустая реализация

Returns

void

Overrides

FormNode.onMarkAsPristine


onMarkAsTouched()

protected onMarkAsTouched(): void;

Defined in: core/nodes/group-node.ts:433

Hook: вызывается после markAsTouched()

Переопределите в наследниках для дополнительной логики:

  • GroupNode: пометить все дочерние узлы как touched
  • ArrayNode: пометить все элементы массива как touched
  • FieldNode: пустая реализация (нет дочерних узлов)

Returns

void

Example

// GroupNode
protected onMarkAsTouched(): void {
this.fields.forEach(field => field.markAsTouched());
}

Overrides

FormNode.onMarkAsTouched


onMarkAsUntouched()

protected onMarkAsUntouched(): void;

Defined in: core/nodes/group-node.ts:437

Hook: вызывается после markAsUntouched()

Переопределите в наследниках для дополнительной логики:

  • GroupNode: пометить все дочерние узлы как untouched
  • ArrayNode: пометить все элементы массива как untouched
  • FieldNode: пустая реализация (нет дочерних узлов)

Returns

void

Overrides

FormNode.onMarkAsUntouched


patchValue()

patchValue(value): void;

Defined in: core/nodes/group-node.ts:288

Частично обновить значение узла Для FieldNode: работает как setValue Для GroupNode: обновляет только указанные поля Для ArrayNode: обновляет только указанные элементы

Parameters

value

Partial<T>

частичное значение для обновления

Returns

void

Overrides

FormNode.patchValue


reset()

reset(value?): void;

Defined in: core/nodes/group-node.ts:320

Сбросить форму к указанным значениям (или к initialValues)

Parameters

value?

T

опциональный объект со значениями для сброса

Returns

void

Remarks

Рекурсивно вызывает reset() для всех полей формы

Example

// Сброс к initialValues
form.reset();

// Сброс к новым значениям
form.reset({ email: 'new@mail.com', password: '' });

Overrides

FormNode.reset


resetToInitial()

resetToInitial(): void;

Defined in: core/nodes/group-node.ts:331

Сбросить форму к исходным значениям (initialValues)

Returns

void


setErrors()

setErrors(errors): void;

Defined in: core/nodes/group-node.ts:361

Установить form-level validation errors

Parameters

errors

ValidationError[]

Returns

void

Overrides

FormNode.setErrors


setValue()

setValue(value, options?): void;

Defined in: core/nodes/group-node.ts:277

Установить значение узла

Parameters

value

T

новое значение

options?

SetValueOptions

опции установки значения

Returns

void

Overrides

FormNode.setValue


submit()

submit<R>(onSubmit, options?): Promise<R | null>;

Defined in: core/nodes/group-node.ts:460

Отправить форму

Type Parameters

R

R

Parameters

onSubmit

(values) => R | Promise<R>

Callback для отправки данных

options?

SubmitOptions

Опции submit (skipValidation, skipTouch)

Returns

Promise<R | null>

Результат от onSubmit или null если валидация не пройдена


submitWithResult()

submitWithResult<R>(onSubmit, options?): Promise<SubmitResult<R>>;

Defined in: core/nodes/group-node.ts:474

Отправить форму с расширенным результатом

Type Parameters

R

R

Parameters

onSubmit

(values) => R | Promise<R>

Callback для отправки данных

options?

SubmitOptions

Опции submit

Returns

Promise<SubmitResult<R>>

Объект SubmitResult с данными, статусом и возможной ошибкой


touchAll()

touchAll(): void;

Defined in: core/nodes/form-node.ts:354

Пометить все поля (включая вложенные) как touched Алиас для markAsTouched(), но более явно показывает намерение пометить ВСЕ поля рекурсивно

Полезно для:

  • Показа всех ошибок валидации перед submit
  • Принудительного отображения ошибок при нажатии "Validate All"
  • Отображения невалидных полей в wizard/step form

Returns

void

Example

// Показать все ошибки перед submit
form.touchAll();
const isValid = await form.validate();
if (!isValid) {
// Все ошибки теперь видны пользователю
}

// Или использовать submit() который уже вызывает touchAll
await form.submit(async (values) => {
await api.save(values);
});

Inherited from

FormNode.touchAll


validate()

validate(): Promise<boolean>;

Defined in: core/nodes/group-node.ts:341

Запустить валидацию узла

Returns

Promise<boolean>

Promise<boolean> - true если валидация успешна

Overrides

FormNode.validate


watchField()

watchField<K>(fieldPath, callback): () => void;

Defined in: core/nodes/group-node.ts:694

Подписка на изменения вложенного поля по строковому пути Поддерживает вложенные пути типа "address.city"

Type Parameters

K

K extends string | number | symbol

Parameters

fieldPath

K extends string ? K : string

Строковый путь к полю (например, "address.city")

callback

(value) => void | Promise<void>

Функция, вызываемая при изменении поля

Returns

Функция отписки для cleanup

() => void

Example

// Подписка на изменение страны для загрузки городов
const dispose = form.watchField(
'registrationAddress.country',
async (countryCode) => {
if (countryCode) {
const cities = await fetchCitiesByCountry(countryCode);
form.registrationAddress.city.updateComponentProps({
options: cities
});
}
}
);

// Cleanup
useEffect(() => dispose, []);

Properties

_dirty

protected _dirty: Signal<boolean>;

Defined in: core/nodes/form-node.ts:56

Значение узла было изменено (dirty) Protected: наследники могут читать/изменять через методы

Inherited from

FormNode._dirty


_status

protected _status: Signal<FieldStatus>;

Defined in: core/nodes/form-node.ts:62

Текущий статус узла Protected: наследники могут читать/изменять через методы

Inherited from

FormNode._status


_touched

protected _touched: Signal<boolean>;

Defined in: core/nodes/form-node.ts:50

Пользователь взаимодействовал с узлом (touched) Protected: наследники могут читать/изменять через методы

Inherited from

FormNode._touched


dirty

readonly dirty: ReadonlySignal<boolean>;

Defined in: core/nodes/group-node.ts:152

Значение узла было изменено (dirty) Computed из _dirty для предоставления readonly интерфейса

Overrides

FormNode.dirty


disabled

readonly disabled: ReadonlySignal<boolean>;

Defined in: core/nodes/form-node.ts:99

Узел отключен (disabled)

Inherited from

FormNode.disabled


enabled

readonly enabled: ReadonlySignal<boolean>;

Defined in: core/nodes/form-node.ts:104

Узел включен (enabled)

Inherited from

FormNode.enabled


errors

readonly errors: ReadonlySignal<ValidationError[]>;

Defined in: core/nodes/group-node.ts:154

Массив ошибок валидации

Overrides

FormNode.errors


id

id: `${string}-${string}-${string}-${string}-${string}`;

Defined in: core/nodes/group-node.ts:85


invalid

readonly invalid: ReadonlySignal<boolean>;

Defined in: core/nodes/group-node.ts:150

Узел невалиден (есть ошибки валидации)

Overrides

FormNode.invalid


pending

readonly pending: ReadonlySignal<boolean>;

Defined in: core/nodes/group-node.ts:153

Выполняется асинхронная валидация

Overrides

FormNode.pending


pristine

readonly pristine: ReadonlySignal<boolean>;

Defined in: core/nodes/form-node.ts:88

Значение узла не было изменено (pristine)

Inherited from

FormNode.pristine


status

readonly status: ReadonlySignal<FieldStatus>;

Defined in: core/nodes/group-node.ts:155

Текущий статус узла Computed из _status для предоставления readonly интерфейса

Overrides

FormNode.status


submitting

readonly submitting: ReadonlySignal<boolean>;

Defined in: core/nodes/group-node.ts:156


touched

readonly touched: ReadonlySignal<boolean>;

Defined in: core/nodes/group-node.ts:151

Пользователь взаимодействовал с узлом (touched) Computed из _touched для предоставления readonly интерфейса

Overrides

FormNode.touched


untouched

readonly untouched: ReadonlySignal<boolean>;

Defined in: core/nodes/form-node.ts:77

Пользователь не взаимодействовал с узлом (untouched)

Inherited from

FormNode.untouched


valid

readonly valid: ReadonlySignal<boolean>;

Defined in: core/nodes/group-node.ts:149

Узел валиден (все валидаторы прошли успешно)

Overrides

FormNode.valid


value

readonly value: ReadonlySignal<T>;

Defined in: core/nodes/group-node.ts:148

Текущее значение узла

  • Для FieldNode: значение поля
  • Для GroupNode: объект со значениями всех полей
  • Для ArrayNode: массив значений элементов

Overrides

FormNode.value