forked from p96170835/amis
form 渲染性能优化
This commit is contained in:
parent
d93f311f6f
commit
ecefaab794
|
@ -43,7 +43,10 @@ interface CheckboxProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Checkbox extends React.Component<CheckboxProps, any> {
|
export class Checkbox extends React.Component<CheckboxProps, any> {
|
||||||
static defaultProps = {
|
static defaultProps: Pick<
|
||||||
|
CheckboxProps,
|
||||||
|
'trueValue' | 'falseValue' | 'type'
|
||||||
|
> = {
|
||||||
trueValue: true,
|
trueValue: true,
|
||||||
falseValue: false,
|
falseValue: false,
|
||||||
type: 'checkbox'
|
type: 'checkbox'
|
||||||
|
|
|
@ -6,7 +6,6 @@ import chunk = require('lodash/chunk');
|
||||||
|
|
||||||
export interface CheckboxesProps extends OptionsControlProps {
|
export interface CheckboxesProps extends OptionsControlProps {
|
||||||
placeholder?: any;
|
placeholder?: any;
|
||||||
disabled?: boolean;
|
|
||||||
itemClassName?: string;
|
itemClassName?: string;
|
||||||
columnsCount?: number;
|
columnsCount?: number;
|
||||||
labelClassName?: string;
|
labelClassName?: string;
|
||||||
|
|
|
@ -107,6 +107,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
||||||
];
|
];
|
||||||
|
|
||||||
subForms: Array<any> = [];
|
subForms: Array<any> = [];
|
||||||
|
subFormDefaultValues: Array<{index: number; values: any}> = [];
|
||||||
keys: Array<string> = [];
|
keys: Array<string> = [];
|
||||||
dragTip?: HTMLElement;
|
dragTip?: HTMLElement;
|
||||||
sortable?: Sortable;
|
sortable?: Sortable;
|
||||||
|
@ -326,19 +327,31 @@ export default class ComboControl extends React.Component<ComboProps> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = this.getValueAsArray();
|
this.subFormDefaultValues.push({
|
||||||
const newValue = flat ? values.flat : {...values};
|
index,
|
||||||
|
values
|
||||||
|
});
|
||||||
|
|
||||||
if (!isObjectShallowModified(value[index], newValue)) {
|
if (this.subFormDefaultValues.length !== this.subForms.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
value[index] = flat ? values.flat : {...values};
|
let value = this.getValueAsArray();
|
||||||
|
this.subFormDefaultValues.forEach(({index, values}) => {
|
||||||
|
const newValue = flat ? values.flat : {...values};
|
||||||
|
|
||||||
|
if (!isObjectShallowModified(value[index], newValue)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
value[index] = flat ? values.flat : {...values};
|
||||||
|
});
|
||||||
|
|
||||||
if (flat && joinValues) {
|
if (flat && joinValues) {
|
||||||
value = value.join(delimiter || ',');
|
value = value.join(delimiter || ',');
|
||||||
}
|
}
|
||||||
this.props.onChange(value);
|
|
||||||
|
this.props.setPrinstineValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSingleFormInit(values: any) {
|
handleSingleFormInit(values: any) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {anyChanged, promisify, isObject, getVariable} from '../../utils/helper';
|
||||||
import {Schema} from '../../types';
|
import {Schema} from '../../types';
|
||||||
import {IIRendererStore} from '../../store';
|
import {IIRendererStore} from '../../store';
|
||||||
import {ScopedContext, IScopedContext} from '../../Scoped';
|
import {ScopedContext, IScopedContext} from '../../Scoped';
|
||||||
|
import {reaction} from 'mobx';
|
||||||
|
|
||||||
export interface ControlProps extends RendererProps {
|
export interface ControlProps extends RendererProps {
|
||||||
control: {
|
control: {
|
||||||
|
@ -35,15 +36,25 @@ export interface ControlProps extends RendererProps {
|
||||||
removeHook: (fn: () => any) => void;
|
removeHook: (fn: () => any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class FormControl extends React.Component<ControlProps> {
|
interface ControlState {
|
||||||
|
value: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class FormControl extends React.PureComponent<
|
||||||
|
ControlProps,
|
||||||
|
ControlState
|
||||||
|
> {
|
||||||
public model: IFormItemStore | undefined;
|
public model: IFormItemStore | undefined;
|
||||||
control: any;
|
control: any;
|
||||||
hook?: () => any;
|
hook?: () => any;
|
||||||
hook2?: () => any;
|
hook2?: () => any;
|
||||||
|
reaction?: () => void;
|
||||||
|
|
||||||
static defaultProps: Partial<ControlProps> = {};
|
static defaultProps = {};
|
||||||
|
|
||||||
lazyValidate: Function;
|
lazyValidate: Function;
|
||||||
|
lazyEmitChange: (value: any, submitOnChange: boolean) => void;
|
||||||
|
state = {value: this.props.control.value};
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
const {
|
const {
|
||||||
formStore: form,
|
formStore: form,
|
||||||
|
@ -76,12 +87,16 @@ export default class FormControl extends React.Component<ControlProps> {
|
||||||
trailing: true,
|
trailing: true,
|
||||||
leading: false
|
leading: false
|
||||||
});
|
});
|
||||||
|
this.lazyEmitChange = debouce(this.emitChange.bind(this), 250, {
|
||||||
|
trailing: true,
|
||||||
|
leading: false
|
||||||
|
});
|
||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.model = form.registryItem(name, {
|
const model = (this.model = form.registryItem(name, {
|
||||||
id,
|
id,
|
||||||
type,
|
type,
|
||||||
required,
|
required,
|
||||||
|
@ -95,7 +110,7 @@ export default class FormControl extends React.Component<ControlProps> {
|
||||||
labelField,
|
labelField,
|
||||||
joinValues,
|
joinValues,
|
||||||
extractValue
|
extractValue
|
||||||
});
|
}));
|
||||||
|
|
||||||
if (
|
if (
|
||||||
this.model.unique &&
|
this.model.unique &&
|
||||||
|
@ -105,6 +120,15 @@ export default class FormControl extends React.Component<ControlProps> {
|
||||||
const combo = form.parentStore as IComboStore;
|
const combo = form.parentStore as IComboStore;
|
||||||
combo.bindUniuqueItem(this.model);
|
combo.bindUniuqueItem(this.model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 同步 value
|
||||||
|
this.setState({
|
||||||
|
value: model.value
|
||||||
|
});
|
||||||
|
this.reaction = reaction(
|
||||||
|
() => model.value,
|
||||||
|
value => this.setState({value})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
@ -118,7 +142,7 @@ export default class FormControl extends React.Component<ControlProps> {
|
||||||
if (name && form !== store) {
|
if (name && form !== store) {
|
||||||
const value = getVariable(store.data, name);
|
const value = getVariable(store.data, name);
|
||||||
if (typeof value !== 'undefined' && value !== this.getValue()) {
|
if (typeof value !== 'undefined' && value !== this.getValue()) {
|
||||||
this.handleChange(value);
|
this.emitChange(value, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +175,7 @@ export default class FormControl extends React.Component<ControlProps> {
|
||||||
this.model && this.disposeModel();
|
this.model && this.disposeModel();
|
||||||
|
|
||||||
// name 是后面才有的,比如编辑模式下就会出现。
|
// name 是后面才有的,比如编辑模式下就会出现。
|
||||||
this.model = form.registryItem(nextProps.control.name, {
|
const model = (this.model = form.registryItem(nextProps.control.name, {
|
||||||
id: nextProps.control.id,
|
id: nextProps.control.id,
|
||||||
type: nextProps.control.type,
|
type: nextProps.control.type,
|
||||||
required: nextProps.control.required,
|
required: nextProps.control.required,
|
||||||
|
@ -165,8 +189,16 @@ export default class FormControl extends React.Component<ControlProps> {
|
||||||
joinValues: nextProps.control.joinValues,
|
joinValues: nextProps.control.joinValues,
|
||||||
extractValue: nextProps.control.extractValue,
|
extractValue: nextProps.control.extractValue,
|
||||||
messages: nextProps.control.validationErrors
|
messages: nextProps.control.validationErrors
|
||||||
});
|
}));
|
||||||
// this.forceUpdate();
|
// this.forceUpdate();
|
||||||
|
this.setState({
|
||||||
|
value: model.value
|
||||||
|
});
|
||||||
|
this.reaction && this.reaction();
|
||||||
|
this.reaction = reaction(
|
||||||
|
() => model.value,
|
||||||
|
value => this.setState({value})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
@ -227,7 +259,7 @@ export default class FormControl extends React.Component<ControlProps> {
|
||||||
(value = getVariable(data as any, name)) !==
|
(value = getVariable(data as any, name)) !==
|
||||||
getVariable(prevProps.data, name)
|
getVariable(prevProps.data, name)
|
||||||
) {
|
) {
|
||||||
this.handleChange(value);
|
this.emitChange(value, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +267,9 @@ export default class FormControl extends React.Component<ControlProps> {
|
||||||
this.hook && this.props.removeHook(this.hook);
|
this.hook && this.props.removeHook(this.hook);
|
||||||
this.hook2 && this.props.removeHook(this.hook2);
|
this.hook2 && this.props.removeHook(this.hook2);
|
||||||
this.disposeModel();
|
this.disposeModel();
|
||||||
|
(this.lazyValidate as any).cancel();
|
||||||
|
(this.lazyEmitChange as any).cancel();
|
||||||
|
this.reaction && this.reaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
disposeModel() {
|
disposeModel() {
|
||||||
|
@ -305,18 +340,12 @@ export default class FormControl extends React.Component<ControlProps> {
|
||||||
|
|
||||||
handleChange(
|
handleChange(
|
||||||
value: any,
|
value: any,
|
||||||
submitOnChange: boolean = this.props.control.submitOnChange
|
submitOnChange: boolean = this.props.control.submitOnChange,
|
||||||
|
changeImmediately: boolean = false
|
||||||
) {
|
) {
|
||||||
const {
|
const {
|
||||||
formStore: form,
|
|
||||||
onChange,
|
onChange,
|
||||||
control: {
|
control: {type}
|
||||||
validateOnChange,
|
|
||||||
name,
|
|
||||||
pipeOut,
|
|
||||||
onChange: onFormItemChange,
|
|
||||||
type
|
|
||||||
}
|
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
// todo 以后想办法不要強耦合类型。
|
// todo 以后想办法不要強耦合类型。
|
||||||
|
@ -324,6 +353,31 @@ export default class FormControl extends React.Component<ControlProps> {
|
||||||
onChange && onChange(...(arguments as any));
|
onChange && onChange(...(arguments as any));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
value
|
||||||
|
},
|
||||||
|
() =>
|
||||||
|
changeImmediately
|
||||||
|
? this.emitChange(value, submitOnChange)
|
||||||
|
: this.lazyEmitChange(value, submitOnChange)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitChange(
|
||||||
|
value: any,
|
||||||
|
submitOnChange: boolean = this.props.control.submitOnChange
|
||||||
|
) {
|
||||||
|
const {
|
||||||
|
formStore: form,
|
||||||
|
onChange,
|
||||||
|
control: {validateOnChange, name, pipeOut, onChange: onFormItemChange}
|
||||||
|
} = this.props;
|
||||||
|
if (!this.model) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const oldValue = this.model.value;
|
const oldValue = this.model.value;
|
||||||
|
|
||||||
if (pipeOut) {
|
if (pipeOut) {
|
||||||
|
@ -411,11 +465,8 @@ export default class FormControl extends React.Component<ControlProps> {
|
||||||
}
|
}
|
||||||
|
|
||||||
getValue() {
|
getValue() {
|
||||||
const {control, formStore: form} = this.props;
|
const {formStore: form, control} = this.props;
|
||||||
|
let value: any = this.state.value;
|
||||||
const model = this.model;
|
|
||||||
// let value:any = model ? (typeof model.value === 'undefined' ? '' : model.value) : (control.value || '');
|
|
||||||
let value: any = model ? model.value : control.value;
|
|
||||||
|
|
||||||
if (control.pipeIn) {
|
if (control.pipeIn) {
|
||||||
value = control.pipeIn(value, form.data);
|
value = control.pipeIn(value, form.data);
|
||||||
|
|
|
@ -664,6 +664,63 @@ export class FormItemWrap extends React.Component<FormItemProps> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 白名单形式,只有这些属性发生变化,才会往下更新。
|
||||||
|
// 除非配置 strictMode
|
||||||
|
export const detectProps = [
|
||||||
|
// 'formPristine', // 理论来说,不需要,因为 formPristine 更新到时候 value 肯定也会更新。
|
||||||
|
'addable',
|
||||||
|
'addButtonClassName',
|
||||||
|
'addButtonText',
|
||||||
|
'addOn',
|
||||||
|
'btnClassName',
|
||||||
|
'btnLabel',
|
||||||
|
'btnDisabled',
|
||||||
|
'className',
|
||||||
|
'clearable',
|
||||||
|
'columns',
|
||||||
|
'columnsCount',
|
||||||
|
'controls',
|
||||||
|
'desc',
|
||||||
|
'description',
|
||||||
|
'disabled',
|
||||||
|
'draggable',
|
||||||
|
'editable',
|
||||||
|
'editButtonClassName',
|
||||||
|
'formHorizontal',
|
||||||
|
'formMode',
|
||||||
|
'hideRoot',
|
||||||
|
'horizontal',
|
||||||
|
'icon',
|
||||||
|
'inline',
|
||||||
|
'inputClassName',
|
||||||
|
'label',
|
||||||
|
'labelClassName',
|
||||||
|
'labelField',
|
||||||
|
'language',
|
||||||
|
'level',
|
||||||
|
'max',
|
||||||
|
'maxRows',
|
||||||
|
'min',
|
||||||
|
'minRows',
|
||||||
|
'multiLine',
|
||||||
|
'multiple',
|
||||||
|
'option',
|
||||||
|
'placeholder',
|
||||||
|
'removable',
|
||||||
|
'required',
|
||||||
|
'remark',
|
||||||
|
'hint',
|
||||||
|
'rows',
|
||||||
|
'searchable',
|
||||||
|
'showCompressOptions',
|
||||||
|
'size',
|
||||||
|
'step',
|
||||||
|
'showInput',
|
||||||
|
'unit',
|
||||||
|
'value',
|
||||||
|
'diffValue'
|
||||||
|
];
|
||||||
|
|
||||||
export function registerFormItem(config: FormItemConfig): RendererConfig {
|
export function registerFormItem(config: FormItemConfig): RendererConfig {
|
||||||
let Control = config.component;
|
let Control = config.component;
|
||||||
|
|
||||||
|
@ -700,7 +757,6 @@ export function registerFormItem(config: FormItemConfig): RendererConfig {
|
||||||
renderDescription: config.renderDescription,
|
renderDescription: config.renderDescription,
|
||||||
sizeMutable: config.sizeMutable,
|
sizeMutable: config.sizeMutable,
|
||||||
wrap: config.wrap,
|
wrap: config.wrap,
|
||||||
strictMode: config.strictMode,
|
|
||||||
...Control.defaultProps
|
...Control.defaultProps
|
||||||
};
|
};
|
||||||
static propsList: any = [
|
static propsList: any = [
|
||||||
|
@ -709,6 +765,7 @@ export function registerFormItem(config: FormItemConfig): RendererConfig {
|
||||||
'onChange',
|
'onChange',
|
||||||
'setPrinstineValue',
|
'setPrinstineValue',
|
||||||
'readOnly',
|
'readOnly',
|
||||||
|
'strictMode',
|
||||||
...((Control as any).propsList || [])
|
...((Control as any).propsList || [])
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -736,71 +793,12 @@ export function registerFormItem(config: FormItemConfig): RendererConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps: FormControlProps) {
|
shouldComponentUpdate(nextProps: FormControlProps) {
|
||||||
if (nextProps.strictMode === false) {
|
if (nextProps.strictMode === false || config.strictMode === false) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 把可能会影响视图的白名单弄出来,减少重新渲染次数。
|
// 把可能会影响视图的白名单弄出来,减少重新渲染次数。
|
||||||
if (
|
if (anyChanged(detectProps, this.props, nextProps)) {
|
||||||
anyChanged(
|
|
||||||
[
|
|
||||||
'formPristine',
|
|
||||||
'addable',
|
|
||||||
'addButtonClassName',
|
|
||||||
'addButtonText',
|
|
||||||
'addOn',
|
|
||||||
'btnClassName',
|
|
||||||
'btnLabel',
|
|
||||||
'btnDisabled',
|
|
||||||
'className',
|
|
||||||
'clearable',
|
|
||||||
'columns',
|
|
||||||
'columnsCount',
|
|
||||||
'controls',
|
|
||||||
'desc',
|
|
||||||
'description',
|
|
||||||
'disabled',
|
|
||||||
'draggable',
|
|
||||||
'editable',
|
|
||||||
'editButtonClassName',
|
|
||||||
'formHorizontal',
|
|
||||||
'formMode',
|
|
||||||
'hideRoot',
|
|
||||||
'horizontal',
|
|
||||||
'icon',
|
|
||||||
'inline',
|
|
||||||
'inputClassName',
|
|
||||||
'label',
|
|
||||||
'labelClassName',
|
|
||||||
'labelField',
|
|
||||||
'language',
|
|
||||||
'level',
|
|
||||||
'max',
|
|
||||||
'maxRows',
|
|
||||||
'min',
|
|
||||||
'minRows',
|
|
||||||
'multiLine',
|
|
||||||
'multiple',
|
|
||||||
'option',
|
|
||||||
'placeholder',
|
|
||||||
'removable',
|
|
||||||
'required',
|
|
||||||
'remark',
|
|
||||||
'hint',
|
|
||||||
'rows',
|
|
||||||
'searchable',
|
|
||||||
'showCompressOptions',
|
|
||||||
'size',
|
|
||||||
'step',
|
|
||||||
'showInput',
|
|
||||||
'unit',
|
|
||||||
'value',
|
|
||||||
'diffValue'
|
|
||||||
],
|
|
||||||
this.props,
|
|
||||||
nextProps
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,12 @@ import {
|
||||||
getTree
|
getTree
|
||||||
} from '../../utils/helper';
|
} from '../../utils/helper';
|
||||||
import {reaction} from 'mobx';
|
import {reaction} from 'mobx';
|
||||||
import {FormControlProps, registerFormItem, FormItemBasicConfig} from './Item';
|
import {
|
||||||
|
FormControlProps,
|
||||||
|
registerFormItem,
|
||||||
|
FormItemBasicConfig,
|
||||||
|
detectProps as itemDetectProps
|
||||||
|
} from './Item';
|
||||||
import {IFormItemStore} from '../../store/formItem';
|
import {IFormItemStore} from '../../store/formItem';
|
||||||
export type OptionsControlComponent = React.ComponentType<FormControlProps>;
|
export type OptionsControlComponent = React.ComponentType<FormControlProps>;
|
||||||
|
|
||||||
|
@ -71,6 +76,21 @@ export interface OptionsProps extends FormControlProps, OptionProps {
|
||||||
optionLabel?: string;
|
optionLabel?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const detectProps = itemDetectProps.concat([
|
||||||
|
'options',
|
||||||
|
'size',
|
||||||
|
'buttons',
|
||||||
|
'columnsCount',
|
||||||
|
'multiple',
|
||||||
|
'hideRoot',
|
||||||
|
'checkAll',
|
||||||
|
'showIcon',
|
||||||
|
'showRadio',
|
||||||
|
'btnDisabled',
|
||||||
|
'joinValues',
|
||||||
|
'extractValue'
|
||||||
|
]);
|
||||||
|
|
||||||
export function registerOptionsControl(config: OptionsConfig) {
|
export function registerOptionsControl(config: OptionsConfig) {
|
||||||
const Control = config.component;
|
const Control = config.component;
|
||||||
|
|
||||||
|
@ -93,7 +113,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||||
: [];
|
: [];
|
||||||
static ComposedComponent = Control;
|
static ComposedComponent = Control;
|
||||||
|
|
||||||
reaction: any;
|
reaction?: () => void;
|
||||||
input: any;
|
input: any;
|
||||||
|
|
||||||
componentWillMount() {
|
componentWillMount() {
|
||||||
|
@ -110,19 +130,15 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||||
addHook,
|
addHook,
|
||||||
formInited,
|
formInited,
|
||||||
valueField,
|
valueField,
|
||||||
options
|
options,
|
||||||
|
value
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (formItem) {
|
if (formItem) {
|
||||||
formItem.setOptions(normalizeOptions(options));
|
formItem.setOptions(normalizeOptions(options));
|
||||||
|
|
||||||
this.reaction = reaction(
|
this.reaction = reaction(
|
||||||
() =>
|
() => JSON.stringify([formItem.loading, formItem.filteredOptions]),
|
||||||
JSON.stringify([
|
|
||||||
formItem.loading,
|
|
||||||
formItem.selectedOptions,
|
|
||||||
formItem.filteredOptions
|
|
||||||
]),
|
|
||||||
() => this.forceUpdate()
|
() => this.forceUpdate()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -140,12 +156,15 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||||
|
|
||||||
if (formItem && joinValues === false && defaultValue) {
|
if (formItem && joinValues === false && defaultValue) {
|
||||||
const selectedOptions = extractValue
|
const selectedOptions = extractValue
|
||||||
? formItem.selectedOptions.map(
|
? formItem
|
||||||
(selectedOption: Option) => selectedOption[valueField || 'value']
|
.getSelectedOptions(value)
|
||||||
)
|
.map(
|
||||||
: formItem.selectedOptions;
|
(selectedOption: Option) =>
|
||||||
|
selectedOption[valueField || 'value']
|
||||||
|
)
|
||||||
|
: formItem.getSelectedOptions(value);
|
||||||
setPrinstineValue(
|
setPrinstineValue(
|
||||||
multiple ? selectedOptions.concat() : formItem.selectedOptions[0]
|
multiple ? selectedOptions.concat() : selectedOptions[0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,37 +183,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (anyChanged(detectProps, this.props, nextProps)) {
|
||||||
anyChanged(
|
|
||||||
[
|
|
||||||
'formPristine',
|
|
||||||
'addOn',
|
|
||||||
'disabled',
|
|
||||||
'placeholder',
|
|
||||||
'required',
|
|
||||||
'formMode',
|
|
||||||
'className',
|
|
||||||
'inputClassName',
|
|
||||||
'labelClassName',
|
|
||||||
'label',
|
|
||||||
'inline',
|
|
||||||
'options',
|
|
||||||
'size',
|
|
||||||
'btnClassName',
|
|
||||||
'btnActiveClassName',
|
|
||||||
'buttons',
|
|
||||||
'columnsCount',
|
|
||||||
'multiple',
|
|
||||||
'hideRoot',
|
|
||||||
'checkAll',
|
|
||||||
'showIcon',
|
|
||||||
'showRadio',
|
|
||||||
'btnDisabled'
|
|
||||||
],
|
|
||||||
this.props,
|
|
||||||
nextProps
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,10 +269,9 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||||
extractValue === false &&
|
extractValue === false &&
|
||||||
(typeof value === 'string' || typeof value === 'number')
|
(typeof value === 'string' || typeof value === 'number')
|
||||||
) {
|
) {
|
||||||
|
const selectedOptions = formItem.getSelectedOptions(value);
|
||||||
formItem.changeValue(
|
formItem.changeValue(
|
||||||
multiple
|
multiple ? selectedOptions.concat() : selectedOptions[0]
|
||||||
? formItem.selectedOptions.concat()
|
|
||||||
: formItem.selectedOptions[0]
|
|
||||||
);
|
);
|
||||||
} else if (
|
} else if (
|
||||||
extractValue === true &&
|
extractValue === true &&
|
||||||
|
@ -297,9 +285,11 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||||
typeof value === 'number'
|
typeof value === 'number'
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
const selectedOptions = formItem.selectedOptions.map(
|
const selectedOptions = formItem
|
||||||
(selectedOption: Option) => selectedOption[valueField || 'value']
|
.getSelectedOptions(value)
|
||||||
);
|
.map(
|
||||||
|
(selectedOption: Option) => selectedOption[valueField || 'value']
|
||||||
|
);
|
||||||
formItem.changeValue(
|
formItem.changeValue(
|
||||||
multiple ? selectedOptions.concat() : selectedOptions[0]
|
multiple ? selectedOptions.concat() : selectedOptions[0]
|
||||||
);
|
);
|
||||||
|
@ -326,14 +316,15 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||||
clearable,
|
clearable,
|
||||||
resetValue,
|
resetValue,
|
||||||
multiple,
|
multiple,
|
||||||
formItem
|
formItem,
|
||||||
|
value
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
if (!formItem) {
|
if (!formItem) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let valueArray = formItem.selectedOptions.concat();
|
let valueArray = formItem.getSelectedOptions(value).concat();
|
||||||
const idx = valueArray.indexOf(option);
|
const idx = valueArray.indexOf(option);
|
||||||
let newValue: string | Array<Option> | Option = '';
|
let newValue: string | Array<Option> | Option = '';
|
||||||
|
|
||||||
|
@ -375,6 +366,7 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||||
@autobind
|
@autobind
|
||||||
handleToggleAll() {
|
handleToggleAll() {
|
||||||
const {
|
const {
|
||||||
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
joinValues,
|
joinValues,
|
||||||
extractValue,
|
extractValue,
|
||||||
|
@ -389,8 +381,9 @@ export function registerOptionsControl(config: OptionsConfig) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const selectedOptions = formItem.getSelectedOptions(value);
|
||||||
let valueArray =
|
let valueArray =
|
||||||
formItem.selectedOptions.length === formItem.filteredOptions.length
|
selectedOptions.length === formItem.filteredOptions.length
|
||||||
? []
|
? []
|
||||||
: formItem.filteredOptions.concat();
|
: formItem.filteredOptions.concat();
|
||||||
|
|
||||||
|
|
|
@ -187,9 +187,14 @@ export const FormStore = ServiceStore.named('FormStore')
|
||||||
self.updateData(data);
|
self.updateData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncOptions() {
|
const syncOptions = debounce(
|
||||||
self.items.forEach(item => item.syncOptions());
|
() => self.items.forEach(item => item.syncOptions()),
|
||||||
}
|
250,
|
||||||
|
{
|
||||||
|
trailing: true,
|
||||||
|
leading: false
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const saveRemote: (
|
const saveRemote: (
|
||||||
api: Api,
|
api: Api,
|
||||||
|
@ -448,12 +453,18 @@ export const FormStore = ServiceStore.named('FormStore')
|
||||||
self.inited = value;
|
self.inited = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
const setPersistData = debounce(() => {
|
const setPersistData = debounce(
|
||||||
localStorage.setItem(
|
() =>
|
||||||
location.pathname + self.path,
|
localStorage.setItem(
|
||||||
JSON.stringify(self.data)
|
location.pathname + self.path,
|
||||||
);
|
JSON.stringify(self.data)
|
||||||
}, 250);
|
),
|
||||||
|
250,
|
||||||
|
{
|
||||||
|
trailing: true,
|
||||||
|
leading: false
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
function getPersistData() {
|
function getPersistData() {
|
||||||
self.persistData = true;
|
self.persistData = true;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {IRendererStore} from '.';
|
||||||
import {normalizeOptions} from '../components/Select';
|
import {normalizeOptions} from '../components/Select';
|
||||||
import find = require('lodash/find');
|
import find = require('lodash/find');
|
||||||
import {SimpleMap} from '../utils/SimpleMap';
|
import {SimpleMap} from '../utils/SimpleMap';
|
||||||
|
import memoize = require('lodash/memoize');
|
||||||
|
|
||||||
interface IOption {
|
interface IOption {
|
||||||
value?: string | number | null;
|
value?: string | number | null;
|
||||||
|
@ -105,10 +106,8 @@ export const FormItemStore = types
|
||||||
return getLastOptionValue();
|
return getLastOptionValue();
|
||||||
},
|
},
|
||||||
|
|
||||||
getSelectedOptions(value: any = getValue()) {
|
getSelectedOptions: memoize((value: any = getValue()) => {
|
||||||
if (value === getValue()) {
|
if (typeof value === 'undefined') {
|
||||||
return self.selectedOptions;
|
|
||||||
} else if (typeof value === 'undefined') {
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +164,7 @@ export const FormItemStore = types
|
||||||
});
|
});
|
||||||
|
|
||||||
return selectedOptions;
|
return selectedOptions;
|
||||||
}
|
})
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue