优化 types 问题
This commit is contained in:
parent
f5c65fa004
commit
ea8370e6b0
|
@ -13,7 +13,8 @@ import {RendererEnv, RendererProps} from './factory';
|
||||||
import {noop, autobind, qsstringify} from './utils/helper';
|
import {noop, autobind, qsstringify} from './utils/helper';
|
||||||
import {RendererData, Action} from './types';
|
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;
|
doAction?: (action: Action, data: RendererData, throwErrors?: boolean) => void;
|
||||||
receive?: (values: RendererData, subPath?: string) => void;
|
receive?: (values: RendererData, subPath?: string) => void;
|
||||||
reload?: (subPath?: string, query?: RendererData | null, ctx?: RendererData) => void;
|
reload?: (subPath?: string, query?: RendererData | null, ctx?: RendererData) => void;
|
||||||
|
|
|
@ -156,6 +156,7 @@ interface SelectProps {
|
||||||
checkAllLabel?: string;
|
checkAllLabel?: string;
|
||||||
defaultCheckAll?: boolean;
|
defaultCheckAll?: boolean;
|
||||||
simpleValue?: boolean;
|
simpleValue?: boolean;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SelectState {
|
interface SelectState {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {Schema} from '../../types';
|
||||||
import {IIRendererStore} from '../../store';
|
import {IIRendererStore} from '../../store';
|
||||||
import {ScopedContext, IScopedContext} from '../../Scoped';
|
import {ScopedContext, IScopedContext} from '../../Scoped';
|
||||||
|
|
||||||
export interface FormControlProps extends RendererProps {
|
export interface ControlProps extends RendererProps {
|
||||||
control: {
|
control: {
|
||||||
id?: string;
|
id?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
@ -36,13 +36,13 @@ export interface FormControlProps extends RendererProps {
|
||||||
removeHook: (fn: () => any) => void;
|
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;
|
public model: IFormItemStore | undefined;
|
||||||
control: any;
|
control: any;
|
||||||
hook?: () => any;
|
hook?: () => any;
|
||||||
hook2?: () => any;
|
hook2?: () => any;
|
||||||
|
|
||||||
static defaultProps: Partial<FormControlProps> = {};
|
static defaultProps: Partial<ControlProps> = {};
|
||||||
|
|
||||||
lazyValidate: Function;
|
lazyValidate: Function;
|
||||||
componentWillMount() {
|
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 props = this.props;
|
||||||
const form = nextProps.formStore;
|
const form = nextProps.formStore;
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ export default class FormControl extends React.Component<FormControlProps, any>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps: FormControlProps) {
|
componentDidUpdate(prevProps: ControlProps) {
|
||||||
const {
|
const {
|
||||||
store,
|
store,
|
||||||
formStore: form,
|
formStore: form,
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import hoistNonReactStatic = require('hoist-non-react-statics');
|
import hoistNonReactStatic = require('hoist-non-react-statics');
|
||||||
import {IFormItemStore} from '../../store/form';
|
import {IFormItemStore, IFormStore} from '../../store/form';
|
||||||
import {reaction} from 'mobx';
|
import {reaction} from 'mobx';
|
||||||
|
|
||||||
import {RendererProps, registerRenderer, TestFunc, RendererConfig, HocStoreFactory} from '../../factory';
|
import {RendererProps, registerRenderer, TestFunc, RendererConfig, HocStoreFactory} from '../../factory';
|
||||||
import {anyChanged, ucFirst, getWidthRate} from '../../utils/helper';
|
import {anyChanged, ucFirst, getWidthRate} from '../../utils/helper';
|
||||||
import {observer} from 'mobx-react';
|
import {observer} from 'mobx-react';
|
||||||
|
import {FormHorizontal, FormSchema} from '.';
|
||||||
|
|
||||||
export interface FormItemBasicConfig extends Partial<RendererConfig> {
|
export interface FormItemBasicConfig extends Partial<RendererConfig> {
|
||||||
type?: string;
|
type?: string;
|
||||||
|
@ -26,28 +27,40 @@ export interface FormItemBasicConfig extends Partial<RendererConfig> {
|
||||||
validate?: (values: any, value: any) => string | boolean;
|
validate?: (values: any, value: any) => string | boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormControlProps extends RendererProps {
|
export interface FormItemState {
|
||||||
// error string
|
isFocused: boolean;
|
||||||
error?: string;
|
}
|
||||||
inputOnly?: boolean;
|
|
||||||
|
|
||||||
// error 详情
|
|
||||||
errors?: {
|
|
||||||
[propName: string]: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
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;
|
defaultValue: any;
|
||||||
value: any;
|
value: any;
|
||||||
onChange: (value: any, submitOnChange?: boolean) => void;
|
|
||||||
onBulkChange: (values: any, submitOnChange?: boolean) => void;
|
|
||||||
|
|
||||||
prinstine: any;
|
prinstine: any;
|
||||||
setPrinstineValue: (value: any) => void;
|
setPrinstineValue: (value: any) => void;
|
||||||
formMode?: 'default' | 'inline' | 'horizontal' | 'row';
|
onChange: (value: any, submitOnChange?: boolean) => void;
|
||||||
formItem?: IFormItemStore;
|
onBulkChange: (values: {[propName: string]: any}, submitOnChange?: boolean) => void;
|
||||||
strictMode?: boolean;
|
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;
|
renderLabel?: boolean;
|
||||||
renderDescription?: boolean;
|
renderDescription?: boolean;
|
||||||
sizeMutable?: boolean;
|
sizeMutable?: boolean;
|
||||||
|
@ -55,23 +68,43 @@ export interface FormControlProps extends RendererProps {
|
||||||
hint?: string;
|
hint?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
descriptionClassName?: string;
|
descriptionClassName?: string;
|
||||||
|
// error 详情
|
||||||
|
errors?: {
|
||||||
|
[propName: string]: string;
|
||||||
|
};
|
||||||
|
// error string
|
||||||
|
error?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormControlState {
|
export type FormControlProps = RendererProps &
|
||||||
isFocused: boolean;
|
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 type FormControlComponent = React.ComponentType<FormControlProps>;
|
||||||
|
|
||||||
export interface FormItemConfig extends FormItemBasicConfig {
|
export interface FormItemConfig extends FormItemBasicConfig {
|
||||||
component: FormControlComponent;
|
component: FormControlComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FormItemWrap extends React.Component<FormControlProps, FormControlState> {
|
export class FormItemWrap extends React.Component<FormItemProps, FormItemState> {
|
||||||
reaction: any;
|
reaction: any;
|
||||||
|
|
||||||
constructor(props: FormControlProps) {
|
constructor(props: FormItemProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
|
@ -603,7 +636,7 @@ export function registerFormItem(config: FormItemConfig): RendererConfig {
|
||||||
|
|
||||||
ref: any;
|
ref: any;
|
||||||
|
|
||||||
constructor(props: FormControlProps) {
|
constructor(props: FormItemProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.refFn = this.refFn.bind(this);
|
this.refFn = this.refFn.bind(this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {Api} from '../../types';
|
import {Api, Schema} from '../../types';
|
||||||
import {buildApi, isEffectiveApi, isValidApi, isApiOutdated} from '../../utils/api';
|
import {buildApi, isEffectiveApi, isValidApi, isApiOutdated} from '../../utils/api';
|
||||||
import {anyChanged} from '../../utils/helper';
|
import {anyChanged} from '../../utils/helper';
|
||||||
import {reaction} from 'mobx';
|
import {reaction} from 'mobx';
|
||||||
|
@ -30,15 +30,33 @@ export interface OptionsControlProps extends FormControlProps, OptionProps {
|
||||||
setOptions: (value: Array<any>) => void;
|
setOptions: (value: Array<any>) => void;
|
||||||
setLoading: (value: boolean) => void;
|
setLoading: (value: boolean) => void;
|
||||||
reloadOptions: () => 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) {
|
export function registerOptionsControl(config: OptionsConfig) {
|
||||||
const Control = config.component;
|
const Control = config.component;
|
||||||
|
|
||||||
// @observer
|
// @observer
|
||||||
class FormOptionsItem extends React.Component<FormControlProps, any> {
|
class FormOptionsItem extends React.Component<OptionsProps, any> {
|
||||||
static displayName = `OptionsControl(${config.type})`;
|
static displayName = `OptionsControl(${config.type})`;
|
||||||
static defaultProps: Partial<FormControlProps> = {
|
static defaultProps = {
|
||||||
delimiter: ',',
|
delimiter: ',',
|
||||||
labelField: 'label',
|
labelField: 'label',
|
||||||
valueField: 'value',
|
valueField: 'value',
|
||||||
|
@ -55,7 +73,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||||
reaction: any;
|
reaction: any;
|
||||||
input: any;
|
input: any;
|
||||||
|
|
||||||
constructor(props: FormControlProps) {
|
constructor(props: OptionsProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
const formItem = props.formItem as IFormItemStore;
|
const formItem = props.formItem as IFormItemStore;
|
||||||
|
@ -114,7 +132,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||||
this.normalizeValue();
|
this.normalizeValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps: FormControlProps) {
|
shouldComponentUpdate(nextProps: OptionsProps) {
|
||||||
if (config.strictMode === false || nextProps.strictMode === false) {
|
if (config.strictMode === false || nextProps.strictMode === false) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -156,7 +174,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps: OptionsControlProps) {
|
componentWillReceiveProps(nextProps: OptionsProps) {
|
||||||
const props = this.props;
|
const props = this.props;
|
||||||
const formItem = nextProps.formItem as IFormItemStore;
|
const formItem = nextProps.formItem as IFormItemStore;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {promisify, difference, until, noop, isObject, isVisible} from '../../uti
|
||||||
import debouce = require('lodash/debounce');
|
import debouce = require('lodash/debounce');
|
||||||
import flatten = require('lodash/flatten');
|
import flatten = require('lodash/flatten');
|
||||||
import find = require('lodash/find');
|
import find = require('lodash/find');
|
||||||
import Scoped, {ScopedContext, IScopedContext} from '../../Scoped';
|
import Scoped, {ScopedContext, IScopedContext, ScopedComponentType} from '../../Scoped';
|
||||||
import {IComboStore} from '../../store/combo';
|
import {IComboStore} from '../../store/combo';
|
||||||
import qs = require('qs');
|
import qs = require('qs');
|
||||||
import {dataMapping} from '../../utils/tpl-builtin';
|
import {dataMapping} from '../../utils/tpl-builtin';
|
||||||
|
@ -145,7 +145,7 @@ export default class Form extends React.Component<FormProps, object> {
|
||||||
asyncCancel: () => void;
|
asyncCancel: () => void;
|
||||||
disposeOnValidate: () => void;
|
disposeOnValidate: () => void;
|
||||||
shouldLoadInitApi: boolean = false;
|
shouldLoadInitApi: boolean = false;
|
||||||
timer: number;
|
timer: NodeJS.Timeout;
|
||||||
mounted: boolean;
|
mounted: boolean;
|
||||||
constructor(props: FormProps) {
|
constructor(props: FormProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -940,8 +940,8 @@ export class FormRenderer extends Form {
|
||||||
if (this.props.autoFocus) {
|
if (this.props.autoFocus) {
|
||||||
const scoped = this.context as IScopedContext;
|
const scoped = this.context as IScopedContext;
|
||||||
const inputs = scoped.getComponents();
|
const inputs = scoped.getComponents();
|
||||||
let focuableInput = find(inputs, (input: any) => input.focus);
|
let focuableInput = find(inputs, input => input.focus) as ScopedComponentType;
|
||||||
focuableInput && setTimeout(() => focuableInput.focus(), 200);
|
focuableInput && setTimeout(() => focuableInput.focus!(), 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {Api, Payload, fetchOptions} from '../types';
|
||||||
import {ComboStore, IComboStore, IUniqueGroup} from './combo';
|
import {ComboStore, IComboStore, IUniqueGroup} from './combo';
|
||||||
import {evalExpression} from '../utils/tpl';
|
import {evalExpression} from '../utils/tpl';
|
||||||
import findIndex = require('lodash/findIndex');
|
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 {flattenTree} from '../utils/helper';
|
||||||
import {IRendererStore} from '.';
|
import {IRendererStore} from '.';
|
||||||
import {normalizeOptions} from '../components/Select';
|
import {normalizeOptions} from '../components/Select';
|
||||||
|
@ -50,7 +50,10 @@ export const FormItemStore = types
|
||||||
options: types.optional(types.array(types.frozen()), []),
|
options: types.optional(types.array(types.frozen()), []),
|
||||||
expressionsInOptions: false,
|
expressionsInOptions: false,
|
||||||
selectedOptions: types.optional(types.frozen(), []),
|
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 => {
|
.views(self => {
|
||||||
function getForm(): any {
|
function getForm(): any {
|
||||||
|
@ -532,6 +535,26 @@ export const FormItemStore = types
|
||||||
clearError();
|
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 {
|
return {
|
||||||
config,
|
config,
|
||||||
changeValue,
|
changeValue,
|
||||||
|
@ -544,7 +567,9 @@ export const FormItemStore = types
|
||||||
syncOptions,
|
syncOptions,
|
||||||
setLoading,
|
setLoading,
|
||||||
setSubStore,
|
setSubStore,
|
||||||
reset
|
reset,
|
||||||
|
openDialog,
|
||||||
|
closeDialog
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue