zent
Version:
一套前端设计语言和基于React的实现
92 lines (91 loc) • 3.47 kB
JavaScript
import { useEffect, useMemo, useState } from 'react';
import { useFormContext } from './context';
import { FieldSetModel, FormStrategy, isFieldSetModel, isModelRef, } from './models';
import { useDestroyOnUnmount } from './utils';
import { get, isSome, or } from './maybe';
import { createModelNotFoundError, createUnexpectedModelTypeError, } from './error';
import isPlainObject from '../../utils/isPlainObject';
import { getFieldSetChildChangeObservable } from './listeners/set';
import { useObservableEagerState } from 'observable-hooks';
function useFieldSetModel(field, parent, strategy) {
var model = useMemo(function () {
var model;
if (typeof field === 'string') {
var m = parent.get(field);
if (strategy === FormStrategy.View) {
if (!m || !isFieldSetModel(m)) {
model = new FieldSetModel({});
var v = {};
var potential = parent.getPatchedValue(field);
if (isSome(potential)) {
var inner = get(potential);
if (isPlainObject(inner)) {
v = inner;
}
}
model.patchedValue = v;
parent.registerChild(field, model);
}
else {
model = m;
}
}
else {
if (!m) {
throw createModelNotFoundError(field);
}
else if (!isFieldSetModel(m)) {
throw createUnexpectedModelTypeError(field, 'FieldSetModel', m);
}
else {
model = m;
}
}
}
else if (isModelRef(field)) {
var m = field.getModel();
if (!m || !isFieldSetModel(m)) {
model = new FieldSetModel({});
model.patchedValue = or(field.patchedValue, function () {
return or(field.initialValue, function () { return ({}); });
});
field.setModel(model);
}
else {
model = m;
}
}
else {
model = field;
}
return model;
}, [field, parent, strategy]);
return model;
}
export function useFieldSet(field, validators) {
if (validators === void 0) { validators = []; }
var _a = useFormContext(), parent = _a.parent, strategy = _a.strategy, form = _a.form;
var model = useFieldSetModel(field, parent, strategy);
if (strategy === FormStrategy.View &&
(typeof field === 'string' || isModelRef(field))) {
model.validators = validators;
}
var childContext = useMemo(function () { return ({
strategy: strategy,
form: form,
parent: model,
}); }, [strategy, form, model]);
useObservableEagerState(model.error$);
useDestroyOnUnmount(field, model, parent);
return [childContext, model];
}
export function useNamedChildModel(fieldSet, name) {
var _a = useState(fieldSet.get(name)), child = _a[0], setChild = _a[1];
useEffect(function () {
var $ = getFieldSetChildChangeObservable(fieldSet, name).subscribe(function (n) {
setChild(fieldSet.get(n));
});
return function () { return $.unsubscribe(); };
}, [fieldSet, name]);
return child;
}