viewModel.ts
Назначение файла
Модуль реализует декларативный API view-model в @nrgyjs/core, связывая контроллерный механизм с props представления и реактивным состоянием.
Общая информация
declareViewModel() строится поверх контроллерного API и withView(). Результатом является view-model, которая обычно содержит:
props: atom-представление входных props;state: atom-представление UI-состояния;- методы действий и бизнес-логики.
Модуль поддерживает как функциональные, так и class-based view-model.
Концептуальная архитектура
Внутренняя организация модуля такова:
BaseViewModelиViewModel<T>описывают форму view-model.InferViewModelProps<T>извлекает тип входных props из atom-поляprops.BaseViewControllerрасширяетBaseControllerи публикуетviewиpropsкак удобные поля класса.ViewModelDeclarationBuilderавтоматически добавляетwithView()и создает декларацию черезapply()или базовый класс черезgetBaseClass().declareViewModel()выступает как перегруженная точка входа: либо сразу принимает factory, либо возвращает builder.
Таким образом view-model переиспользует весь lifecycle контроллера, но при этом остается типизированной относительно props представления.
Описание публичного API
Основные типы
BaseViewModel: базовая форма view-model с опциональнымиpropsиstate.ViewModel<T>: alias для конечного типа view-model.InferViewModelProps<TViewModel>: выводит shape props изviewModel.props.ViewModelFactory<TContext, TViewModel>: фабрика функциональной view-model.ViewModelDeclaration<TViewModel, TContext>: тип декларации view-model.ViewModelClassDeclaration<TViewModel, TContext>: тип class-based декларации.
Классы и функции
BaseViewController<TViewModel, TContext>: базовый класс для class-based view-model.ViewModelDeclarationBuilder<TContext>: builder декларации view-model.declareViewModel(factory?): создает декларацию или builder.
Примеры использования
ts
import { declareViewModel, readonlyAtom } from '@nrgyjs/core';
const CounterViewModel = declareViewModel(({ scope, view }) => {
const value = scope.atom(view.props.initialValue());
return {
state: { value: readonlyAtom(value) },
increase: () => value.update((prev) => prev + 1),
};
});