优化 types 问题

This commit is contained in:
liaoxuezhi 2019-11-07 00:07:26 +08:00
parent f5c65fa004
commit ea8370e6b0
7 changed files with 121 additions and 43 deletions

View File

@ -13,7 +13,8 @@ import {RendererEnv, RendererProps} from './factory';
import {noop, autobind, qsstringify} from './utils/helper';
import {RendererData, Action} from './types';
interface ScopedComponentType extends React.Component<RendererProps> {
export interface ScopedComponentType extends React.Component<RendererProps> {
focus?: () =>void;
doAction?: (action: Action, data: RendererData, throwErrors?: boolean) => void;
receive?: (values: RendererData, subPath?: string) => void;
reload?: (subPath?: string, query?: RendererData | null, ctx?: RendererData) => void;

View File

@ -156,6 +156,7 @@ interface SelectProps {
checkAllLabel?: string;
defaultCheckAll?: boolean;
simpleValue?: boolean;
}
interface SelectState {

View File

@ -10,7 +10,7 @@ import {Schema} from '../../types';
import {IIRendererStore} from '../../store';
import {ScopedContext, IScopedContext} from '../../Scoped';
export interface FormControlProps extends RendererProps {
export interface ControlProps extends RendererProps {
control: {
id?: string;
name?: string;
@ -36,13 +36,13 @@ export interface FormControlProps extends RendererProps {
removeHook: (fn: () => any) => void;
}
export default class FormControl extends React.Component<FormControlProps, any> {
export default class FormControl extends React.Component<ControlProps> {
public model: IFormItemStore | undefined;
control: any;
hook?: () => any;
hook2?: () => any;
static defaultProps: Partial<FormControlProps> = {};
static defaultProps: Partial<ControlProps> = {};
lazyValidate: Function;
componentWillMount() {
@ -134,7 +134,7 @@ export default class FormControl extends React.Component<FormControlProps, any>
}
}
componentWillReceiveProps(nextProps: FormControlProps) {
componentWillReceiveProps(nextProps: ControlProps) {
const props = this.props;
const form = nextProps.formStore;
@ -204,7 +204,7 @@ export default class FormControl extends React.Component<FormControlProps, any>
}
}
componentDidUpdate(prevProps: FormControlProps) {
componentDidUpdate(prevProps: ControlProps) {
const {
store,
formStore: form,

View File

@ -1,11 +1,12 @@
import React from 'react';
import hoistNonReactStatic = require('hoist-non-react-statics');
import {IFormItemStore} from '../../store/form';
import {IFormItemStore, IFormStore} from '../../store/form';
import {reaction} from 'mobx';
import {RendererProps, registerRenderer, TestFunc, RendererConfig, HocStoreFactory} from '../../factory';
import {anyChanged, ucFirst, getWidthRate} from '../../utils/helper';
import {observer} from 'mobx-react';
import {FormHorizontal, FormSchema} from '.';
export interface FormItemBasicConfig extends Partial<RendererConfig> {
type?: string;
@ -26,28 +27,40 @@ export interface FormItemBasicConfig extends Partial<RendererConfig> {
validate?: (values: any, value: any) => string | boolean;
}
export interface FormControlProps extends RendererProps {
// error string
error?: string;
inputOnly?: boolean;
// error 详情
errors?: {
[propName: string]: string;
};
export interface FormItemState {
isFocused: boolean;
}
export interface FormItemProps extends RendererProps {
name?: string;
formStore?: IFormStore;
formInited: boolean;
formMode: 'normal' | 'horizontal' | 'inline' | 'row' | 'default';
formHorizontal: FormHorizontal;
defaultSize?: 'xs' | 'sm' | 'md' | 'lg' | 'full';
size?: 'xs' | 'sm' | 'md' | 'lg' | 'full';
disabled: boolean;
btnDisabled: boolean;
defaultValue: any;
value: any;
onChange: (value: any, submitOnChange?: boolean) => void;
onBulkChange: (values: any, submitOnChange?: boolean) => void;
prinstine: any;
setPrinstineValue: (value: any) => void;
formMode?: 'default' | 'inline' | 'horizontal' | 'row';
formItem?: IFormItemStore;
strictMode?: boolean;
onChange: (value: any, submitOnChange?: boolean) => void;
onBulkChange: (values: {[propName: string]: any}, submitOnChange?: boolean) => void;
addHook: (fn: Function, mode?: 'validate' | 'init') => void;
removeHook: (fn: Function, mode?: 'validate' | 'init') => void;
renderFormItems: (schema: FormSchema, region: string, props: any) => JSX.Element;
onFocus: (e: any) => void;
onBlur: (e: any) => void;
renderControl?: (props: RendererProps) => JSX.Element;
formItemValue: any; // 不建议使用 为了兼容 v1
getValue: () => any; // 不建议使用 为了兼容 v1
setValue: (value: any, key: string) => void; // 不建议使用 为了兼容 v1
inputClassName?: string;
renderControl?: (props: FormControlProps) => JSX.Element;
inputOnly?: boolean;
renderLabel?: boolean;
renderDescription?: boolean;
sizeMutable?: boolean;
@ -55,23 +68,43 @@ export interface FormControlProps extends RendererProps {
hint?: string;
description?: string;
descriptionClassName?: string;
// error 详情
errors?: {
[propName: string]: string;
};
// error string
error?: string;
}
export interface FormControlState {
isFocused: boolean;
}
export type FormControlProps = RendererProps &
Exclude<
FormItemProps,
| 'inputClassName'
| 'renderControl'
| 'defaultSize'
| 'size'
| 'error'
| 'errors'
| 'hint'
| 'descriptionClassName'
| 'inputOnly'
| 'renderLabel'
| 'renderDescription'
| 'sizeMutable'
| 'wrap'
>;
export type FormItemComponent = React.ComponentType<FormControlProps>;
export type FormItemComponent = React.ComponentType<FormItemProps>;
export type FormControlComponent = React.ComponentType<FormControlProps>;
export interface FormItemConfig extends FormItemBasicConfig {
component: FormControlComponent;
}
export class FormItemWrap extends React.Component<FormControlProps, FormControlState> {
export class FormItemWrap extends React.Component<FormItemProps, FormItemState> {
reaction: any;
constructor(props: FormControlProps) {
constructor(props: FormItemProps) {
super(props);
this.state = {
@ -603,7 +636,7 @@ export function registerFormItem(config: FormItemConfig): RendererConfig {
ref: any;
constructor(props: FormControlProps) {
constructor(props: FormItemProps) {
super(props);
this.refFn = this.refFn.bind(this);
}

View File

@ -1,4 +1,4 @@
import {Api} from '../../types';
import {Api, Schema} from '../../types';
import {buildApi, isEffectiveApi, isValidApi, isApiOutdated} from '../../utils/api';
import {anyChanged} from '../../utils/helper';
import {reaction} from 'mobx';
@ -30,15 +30,33 @@ export interface OptionsControlProps extends FormControlProps, OptionProps {
setOptions: (value: Array<any>) => void;
setLoading: (value: boolean) => void;
reloadOptions: () => void;
addable?: boolean;
onAdd?: () => void;
editable?: boolean;
onEdit?: (value: Option) => void;
removable?: boolean;
onDelete?: (value: Option) => void;
}
export interface OptionsProps extends FormControlProps, OptionProps {
sourcce?: Api;
addApi?: Api;
addMode?: 'dialog' | 'normal';
addDialog?: Schema;
editApi?: Api;
editMode?: 'dialog' | 'normal';
editDialog?: Schema;
deleteApi?: Api;
deleteConfirmText?: string;
}
export function registerOptionsControl(config: OptionsConfig) {
const Control = config.component;
// @observer
class FormOptionsItem extends React.Component<FormControlProps, any> {
class FormOptionsItem extends React.Component<OptionsProps, any> {
static displayName = `OptionsControl(${config.type})`;
static defaultProps: Partial<FormControlProps> = {
static defaultProps = {
delimiter: ',',
labelField: 'label',
valueField: 'value',
@ -55,7 +73,7 @@ export function registerOptionsControl(config: OptionsConfig) {
reaction: any;
input: any;
constructor(props: FormControlProps) {
constructor(props: OptionsProps) {
super(props);
const formItem = props.formItem as IFormItemStore;
@ -114,7 +132,7 @@ export function registerOptionsControl(config: OptionsConfig) {
this.normalizeValue();
}
shouldComponentUpdate(nextProps: FormControlProps) {
shouldComponentUpdate(nextProps: OptionsProps) {
if (config.strictMode === false || nextProps.strictMode === false) {
return true;
}
@ -156,7 +174,7 @@ export function registerOptionsControl(config: OptionsConfig) {
return false;
}
componentWillReceiveProps(nextProps: OptionsControlProps) {
componentWillReceiveProps(nextProps: OptionsProps) {
const props = this.props;
const formItem = nextProps.formItem as IFormItemStore;

View File

@ -11,7 +11,7 @@ import {promisify, difference, until, noop, isObject, isVisible} from '../../uti
import debouce = require('lodash/debounce');
import flatten = require('lodash/flatten');
import find = require('lodash/find');
import Scoped, {ScopedContext, IScopedContext} from '../../Scoped';
import Scoped, {ScopedContext, IScopedContext, ScopedComponentType} from '../../Scoped';
import {IComboStore} from '../../store/combo';
import qs = require('qs');
import {dataMapping} from '../../utils/tpl-builtin';
@ -145,7 +145,7 @@ export default class Form extends React.Component<FormProps, object> {
asyncCancel: () => void;
disposeOnValidate: () => void;
shouldLoadInitApi: boolean = false;
timer: number;
timer: NodeJS.Timeout;
mounted: boolean;
constructor(props: FormProps) {
super(props);
@ -940,8 +940,8 @@ export class FormRenderer extends Form {
if (this.props.autoFocus) {
const scoped = this.context as IScopedContext;
const inputs = scoped.getComponents();
let focuableInput = find(inputs, (input: any) => input.focus);
focuableInput && setTimeout(() => focuableInput.focus(), 200);
let focuableInput = find(inputs, input => input.focus) as ScopedComponentType;
focuableInput && setTimeout(() => focuableInput.focus!(), 200);
}
}

View File

@ -5,7 +5,7 @@ import {Api, Payload, fetchOptions} from '../types';
import {ComboStore, IComboStore, IUniqueGroup} from './combo';
import {evalExpression} from '../utils/tpl';
import findIndex = require('lodash/findIndex');
import {isArrayChilrenModified, hasOwnProperty, isObject} from '../utils/helper';
import {isArrayChilrenModified, hasOwnProperty, isObject, createObject} from '../utils/helper';
import {flattenTree} from '../utils/helper';
import {IRendererStore} from '.';
import {normalizeOptions} from '../components/Select';
@ -50,7 +50,10 @@ export const FormItemStore = types
options: types.optional(types.array(types.frozen()), []),
expressionsInOptions: false,
selectedOptions: types.optional(types.frozen(), []),
filteredOptions: types.optional(types.frozen(), [])
filteredOptions: types.optional(types.frozen(), []),
dialogSchema: types.frozen(),
dialogOpen: false,
dialogData: types.frozen(),
})
.views(self => {
function getForm(): any {
@ -532,6 +535,26 @@ export const FormItemStore = types
clearError();
}
function openDialog(schema: any, ctx: any, additonal?: object) {
let proto = ctx.__super ? ctx.__super : self.form.data;
if (additonal) {
proto = createObject(proto, additonal);
}
const data = createObject(proto, {
...ctx
});
self.dialogSchema = schema;
self.dialogData = data;
self.dialogOpen = true;
}
function closeDialog() {
self.dialogOpen = false;
}
return {
config,
changeValue,
@ -544,7 +567,9 @@ export const FormItemStore = types
syncOptions,
setLoading,
setSubStore,
reset
reset,
openDialog,
closeDialog
};
});