forked from p96170835/amis
store 回收问题修复
This commit is contained in:
parent
420aef95ce
commit
8ec9ad0cb3
|
@ -56,7 +56,6 @@
|
|||
"react-addons-update": "15.6.2",
|
||||
"react-color": "2.13.8",
|
||||
"react-cropper": "1.0.0",
|
||||
"react-date-range": "0.9.4",
|
||||
"react-datetime": "2.16.0",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-dropzone": "10.1.10",
|
||||
|
|
|
@ -734,7 +734,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||
wrapWithPanel: false,
|
||||
mode: subFormMode,
|
||||
className: cx(`Combo-form`, formClassName),
|
||||
lazyOnChange: false
|
||||
lazyChange: false
|
||||
},
|
||||
{
|
||||
index,
|
||||
|
@ -907,7 +907,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||
wrapWithPanel: false,
|
||||
mode: multiLine ? subFormMode : 'row',
|
||||
className: cx(`Combo-form`, formClassName),
|
||||
lazyOnChange: false
|
||||
lazyChange: false
|
||||
},
|
||||
{
|
||||
index,
|
||||
|
@ -1043,7 +1043,7 @@ export default class ComboControl extends React.Component<ComboProps> {
|
|||
wrapWithPanel: false,
|
||||
mode: multiLine ? 'normal' : 'row',
|
||||
className: cx(`Combo-form`, formClassName),
|
||||
lazyOnChange: false
|
||||
lazyChange: false
|
||||
},
|
||||
{
|
||||
disabled: disabled,
|
||||
|
|
|
@ -52,8 +52,14 @@ export default class FormControl extends React.PureComponent<
|
|||
|
||||
static defaultProps = {};
|
||||
|
||||
lazyValidate: Function;
|
||||
lazyEmitChange: (submitOnChange: boolean) => void;
|
||||
lazyValidate = debouce(this.validate.bind(this), 250, {
|
||||
trailing: true,
|
||||
leading: false
|
||||
});
|
||||
lazyEmitChange = debouce(this.emitChange.bind(this), 250, {
|
||||
trailing: true,
|
||||
leading: false
|
||||
});
|
||||
state = {value: this.props.control.value};
|
||||
componentWillMount() {
|
||||
const {
|
||||
|
@ -83,14 +89,6 @@ export default class FormControl extends React.PureComponent<
|
|||
this.setPrinstineValue = this.setPrinstineValue.bind(this);
|
||||
this.controlRef = this.controlRef.bind(this);
|
||||
this.handleBlur = this.handleBlur.bind(this);
|
||||
this.lazyValidate = debouce(this.validate.bind(this), 250, {
|
||||
trailing: true,
|
||||
leading: false
|
||||
});
|
||||
this.lazyEmitChange = debouce(this.emitChange.bind(this), 250, {
|
||||
trailing: true,
|
||||
leading: false
|
||||
});
|
||||
|
||||
if (!name) {
|
||||
return;
|
||||
|
@ -165,43 +163,43 @@ export default class FormControl extends React.PureComponent<
|
|||
const props = this.props;
|
||||
const form = nextProps.formStore;
|
||||
|
||||
if (!nextProps.control.name) {
|
||||
// 把 name 删了, 对 model 做清理
|
||||
this.model && this.disposeModel();
|
||||
this.reaction && this.reaction();
|
||||
this.model = undefined;
|
||||
return;
|
||||
} else if (nextProps.control.name !== props.control.name || !this.model) {
|
||||
// 对 model 做清理
|
||||
this.model && this.disposeModel();
|
||||
this.reaction && this.reaction();
|
||||
// if (!nextProps.control.name) {
|
||||
// // 把 name 删了, 对 model 做清理
|
||||
// this.model && this.disposeModel();
|
||||
// this.reaction && this.reaction();
|
||||
// this.model = undefined;
|
||||
// return;
|
||||
// } else if (nextProps.control.name !== props.control.name || !this.model) {
|
||||
// // 对 model 做清理
|
||||
// this.model && this.disposeModel();
|
||||
// this.reaction && this.reaction();
|
||||
|
||||
// name 是后面才有的,比如编辑模式下就会出现。
|
||||
const model = (this.model = form.registryItem(nextProps.control.name, {
|
||||
id: nextProps.control.id,
|
||||
type: nextProps.control.type,
|
||||
required: nextProps.control.required,
|
||||
unique: nextProps.control.unique,
|
||||
value: nextProps.control.value,
|
||||
rules: nextProps.control.validations,
|
||||
multiple: nextProps.control.multiple,
|
||||
delimiter: nextProps.control.delimiter,
|
||||
valueField: nextProps.control.valueField,
|
||||
labelField: nextProps.control.labelField,
|
||||
joinValues: nextProps.control.joinValues,
|
||||
extractValue: nextProps.control.extractValue,
|
||||
messages: nextProps.control.validationErrors
|
||||
}));
|
||||
// this.forceUpdate();
|
||||
this.setState({
|
||||
value: model.value
|
||||
});
|
||||
// // name 是后面才有的,比如编辑模式下就会出现。
|
||||
// const model = (this.model = form.registryItem(nextProps.control.name, {
|
||||
// id: nextProps.control.id,
|
||||
// type: nextProps.control.type,
|
||||
// required: nextProps.control.required,
|
||||
// unique: nextProps.control.unique,
|
||||
// value: nextProps.control.value,
|
||||
// rules: nextProps.control.validations,
|
||||
// multiple: nextProps.control.multiple,
|
||||
// delimiter: nextProps.control.delimiter,
|
||||
// valueField: nextProps.control.valueField,
|
||||
// labelField: nextProps.control.labelField,
|
||||
// joinValues: nextProps.control.joinValues,
|
||||
// extractValue: nextProps.control.extractValue,
|
||||
// messages: nextProps.control.validationErrors
|
||||
// }));
|
||||
// // this.forceUpdate();
|
||||
// this.setState({
|
||||
// value: model.value
|
||||
// });
|
||||
|
||||
this.reaction = reaction(
|
||||
() => model.value,
|
||||
value => this.setState({value})
|
||||
);
|
||||
}
|
||||
// this.reaction = reaction(
|
||||
// () => model.value,
|
||||
// value => this.setState({value})
|
||||
// );
|
||||
// }
|
||||
|
||||
if (
|
||||
this.model &&
|
||||
|
@ -268,10 +266,11 @@ export default class FormControl extends React.PureComponent<
|
|||
componentWillUnmount() {
|
||||
this.hook && this.props.removeHook(this.hook);
|
||||
this.hook2 && this.props.removeHook(this.hook2);
|
||||
this.disposeModel();
|
||||
this.lazyValidate.cancel();
|
||||
// this.lazyEmitChange.flush();
|
||||
this.lazyEmitChange.cancel();
|
||||
this.reaction && this.reaction();
|
||||
(this.lazyValidate as any).cancel();
|
||||
(this.lazyEmitChange as any).cancel();
|
||||
this.disposeModel();
|
||||
}
|
||||
|
||||
disposeModel() {
|
||||
|
@ -348,7 +347,7 @@ export default class FormControl extends React.PureComponent<
|
|||
const {
|
||||
formStore: form,
|
||||
onChange,
|
||||
control: {type, pipeOut},
|
||||
control: {type, pipeOut, changeImmediately: conrolChangeImmediately},
|
||||
formInited
|
||||
} = this.props;
|
||||
|
||||
|
@ -368,7 +367,7 @@ export default class FormControl extends React.PureComponent<
|
|||
value
|
||||
},
|
||||
() =>
|
||||
changeImmediately || !formInited
|
||||
changeImmediately || conrolChangeImmediately || !formInited
|
||||
? this.emitChange(submitOnChange)
|
||||
: this.lazyEmitChange(submitOnChange)
|
||||
);
|
||||
|
@ -521,7 +520,6 @@ export default class FormControl extends React.PureComponent<
|
|||
|
||||
return render('', control, {
|
||||
...rest,
|
||||
key: `${control.name || ''}-${control.type}`, // 很重要:如果不写实际的 control 组件变了,但是 this.control 还是引用的原来那个。
|
||||
defaultSize: controlWidth,
|
||||
disabled: disabled || control.disabled,
|
||||
formItem: model,
|
||||
|
|
|
@ -152,7 +152,7 @@ export default class Form extends React.Component<FormProps, object> {
|
|||
'onFailed',
|
||||
'onFinished',
|
||||
'canAccessSuperData',
|
||||
'lazyOnChange'
|
||||
'lazyChange'
|
||||
];
|
||||
|
||||
hooks: {
|
||||
|
@ -163,7 +163,10 @@ export default class Form extends React.Component<FormProps, object> {
|
|||
shouldLoadInitApi: boolean = false;
|
||||
timer: NodeJS.Timeout;
|
||||
mounted: boolean;
|
||||
lazyHandleChange: (value: any, name: string, submit: boolean) => void;
|
||||
lazyHandleChange = debouce(this.handleChange.bind(this), 250, {
|
||||
trailing: true,
|
||||
leading: false
|
||||
});
|
||||
constructor(props: FormProps) {
|
||||
super(props);
|
||||
|
||||
|
@ -179,10 +182,6 @@ export default class Form extends React.Component<FormProps, object> {
|
|||
this.addHook = this.addHook.bind(this);
|
||||
this.removeHook = this.removeHook.bind(this);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.lazyHandleChange = debouce(this.handleChange, 250, {
|
||||
trailing: true,
|
||||
leading: false
|
||||
});
|
||||
this.renderFormItems = this.renderFormItems.bind(this);
|
||||
this.reload = this.reload.bind(this);
|
||||
this.silentReload = this.silentReload.bind(this);
|
||||
|
@ -303,7 +302,8 @@ export default class Form extends React.Component<FormProps, object> {
|
|||
componentWillUnmount() {
|
||||
this.mounted = false;
|
||||
clearTimeout(this.timer);
|
||||
(this.lazyHandleChange as any).cancel();
|
||||
// this.lazyHandleChange.flush();
|
||||
this.lazyHandleChange.cancel();
|
||||
this.asyncCancel && this.asyncCancel();
|
||||
this.disposeOnValidate && this.disposeOnValidate();
|
||||
const store = this.props.store;
|
||||
|
@ -896,13 +896,15 @@ export default class Form extends React.Component<FormProps, object> {
|
|||
disabled,
|
||||
controlWidth,
|
||||
resolveDefinitions,
|
||||
lazyOnChange
|
||||
lazyChange
|
||||
} = props;
|
||||
|
||||
const subProps = {
|
||||
formStore: form,
|
||||
data: store.data,
|
||||
key,
|
||||
key: `${(control as Schema).name || ''}-${
|
||||
(control as Schema).type
|
||||
}-${key}`,
|
||||
formInited: form.inited,
|
||||
formMode: mode,
|
||||
formHorizontal: horizontal,
|
||||
|
@ -910,8 +912,7 @@ export default class Form extends React.Component<FormProps, object> {
|
|||
disabled: disabled || (control as Schema).disabled || form.loading,
|
||||
btnDisabled: form.loading || form.validating,
|
||||
onAction: this.handleAction,
|
||||
onChange:
|
||||
lazyOnChange !== false ? this.lazyHandleChange : this.handleChange,
|
||||
onChange: this.lazyHandleChange,
|
||||
addHook: this.addHook,
|
||||
removeHook: this.removeHook,
|
||||
renderFormItems: this.renderFormItems,
|
||||
|
@ -919,7 +920,7 @@ export default class Form extends React.Component<FormProps, object> {
|
|||
};
|
||||
|
||||
const subSchema: any =
|
||||
control && (control as Schema).type === 'control'
|
||||
(control as Schema).type === 'control'
|
||||
? control
|
||||
: {
|
||||
type: 'control',
|
||||
|
@ -944,6 +945,7 @@ export default class Form extends React.Component<FormProps, object> {
|
|||
|
||||
control.hiddenOn && (subSchema.hiddenOn = control.hiddenOn);
|
||||
control.visibleOn && (subSchema.visibleOn = control.visibleOn);
|
||||
lazyChange === false && (control.changeImmediately = true);
|
||||
}
|
||||
|
||||
return render(`${region ? `${region}/` : ''}${key}`, subSchema, subProps);
|
||||
|
@ -956,46 +958,23 @@ export default class Form extends React.Component<FormProps, object> {
|
|||
controls,
|
||||
mode,
|
||||
className,
|
||||
classnames: cx
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div className={cx(`Form`, `Form--${mode || 'normal'}`, className)}>
|
||||
{this.renderFormItems({
|
||||
tabs,
|
||||
fieldSet,
|
||||
controls
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
className,
|
||||
wrapWithPanel,
|
||||
render,
|
||||
title,
|
||||
store,
|
||||
panelClassName,
|
||||
debug,
|
||||
headerClassName,
|
||||
footerClassName,
|
||||
actionsClassName,
|
||||
bodyClassName,
|
||||
classPrefix: ns,
|
||||
classnames: cx,
|
||||
debug,
|
||||
$path,
|
||||
affixFooter,
|
||||
mode
|
||||
store,
|
||||
render
|
||||
} = this.props;
|
||||
|
||||
const WrapperComponent =
|
||||
this.props.wrapperComponent ||
|
||||
(/(?:\/|^)form\//.test($path as string) ? 'div' : 'form');
|
||||
|
||||
let body = (
|
||||
<WrapperComponent onSubmit={this.handleFormSubmit} noValidate>
|
||||
return (
|
||||
<WrapperComponent
|
||||
className={cx(`Form`, `Form--${mode || 'normal'}`, className)}
|
||||
onSubmit={this.handleFormSubmit}
|
||||
noValidate
|
||||
>
|
||||
{debug ? (
|
||||
<pre>
|
||||
<code>{JSON.stringify(store.data, null, 2)}</code>
|
||||
|
@ -1004,7 +983,11 @@ export default class Form extends React.Component<FormProps, object> {
|
|||
|
||||
<Spinner show={store.loading} overlay />
|
||||
|
||||
{this.renderBody()}
|
||||
{this.renderFormItems({
|
||||
tabs,
|
||||
fieldSet,
|
||||
controls
|
||||
})}
|
||||
|
||||
{render(
|
||||
'modal',
|
||||
|
@ -1039,6 +1022,24 @@ export default class Form extends React.Component<FormProps, object> {
|
|||
)}
|
||||
</WrapperComponent>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
wrapWithPanel,
|
||||
render,
|
||||
title,
|
||||
store,
|
||||
panelClassName,
|
||||
headerClassName,
|
||||
footerClassName,
|
||||
actionsClassName,
|
||||
bodyClassName,
|
||||
classnames: cx,
|
||||
affixFooter
|
||||
} = this.props;
|
||||
|
||||
let body: JSX.Element = this.renderBody();
|
||||
|
||||
if (wrapWithPanel) {
|
||||
body = render(
|
||||
|
@ -1101,6 +1102,8 @@ export class FormRenderer extends Form {
|
|||
componentWillUnmount() {
|
||||
const scoped = this.context as IScopedContext;
|
||||
scoped.unRegisterComponent(this);
|
||||
|
||||
super.componentWillUnmount();
|
||||
}
|
||||
|
||||
doAction(action: Action, data: object, throwErrors: boolean = false) {
|
||||
|
|
|
@ -42,7 +42,7 @@ export interface FlvSourceProps {
|
|||
order?: number;
|
||||
}
|
||||
|
||||
let currentPlaying: any = null;
|
||||
// let currentPlaying: any = null;
|
||||
|
||||
export class FlvSource extends React.Component<FlvSourceProps, any> {
|
||||
flvPlayer: any;
|
||||
|
@ -262,17 +262,17 @@ export default class Video extends React.Component<VideoProps, VideoState> {
|
|||
videoState: state
|
||||
});
|
||||
|
||||
if (!state.paused) {
|
||||
if (
|
||||
currentPlaying &&
|
||||
currentPlaying.video &&
|
||||
currentPlaying !== player
|
||||
) {
|
||||
currentPlaying.pause();
|
||||
}
|
||||
// if (!state.paused) {
|
||||
// if (
|
||||
// currentPlaying &&
|
||||
// currentPlaying.video &&
|
||||
// currentPlaying !== player
|
||||
// ) {
|
||||
// currentPlaying.pause();
|
||||
// }
|
||||
|
||||
currentPlaying = player;
|
||||
}
|
||||
// currentPlaying = player;
|
||||
// }
|
||||
|
||||
if (!this.frameDom || !this.times) {
|
||||
return;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {types, getRoot, Instance} from 'mobx-state-tree';
|
||||
import {types, getRoot, Instance, destroy} from 'mobx-state-tree';
|
||||
import {extendObject, createObject} from '../utils/helper';
|
||||
import {IRendererStore} from './index';
|
||||
import {dataMapping} from '../utils/tpl-builtin';
|
||||
|
@ -13,7 +13,9 @@ export const iRendererStore = types
|
|||
data: types.optional(types.frozen(), {}),
|
||||
updatedAt: 0, // 从服务端更新时刻
|
||||
pristine: types.optional(types.frozen(), {}),
|
||||
parentId: types.optional(types.string, ''),
|
||||
disposed: false,
|
||||
parentId: '',
|
||||
childrenIds: types.optional(types.array(types.string), []),
|
||||
action: types.optional(types.frozen(), undefined),
|
||||
dialogOpen: false,
|
||||
dialogData: types.optional(types.frozen(), undefined),
|
||||
|
@ -35,6 +37,18 @@ export const iRendererStore = types
|
|||
.actions(self => {
|
||||
const dialogCallbacks = new SimpleMap<(result?: any) => void>();
|
||||
|
||||
function dispose() {
|
||||
// 先标记自己是要销毁的。
|
||||
self.disposed = true;
|
||||
const parent = self.parentStore;
|
||||
|
||||
if (!self.childrenIds.length) {
|
||||
const id = self.id;
|
||||
destroy(self);
|
||||
parent && parent.onChildDispose(id);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
initData(data: object = {}) {
|
||||
self.pristine = data;
|
||||
|
@ -152,7 +166,16 @@ export const iRendererStore = types
|
|||
dialogCallbacks.delete(self.drawerData);
|
||||
setTimeout(() => callback(result), 200);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onChildDispose(childId: string) {
|
||||
const childrenIds = self.childrenIds.filter(item => item !== childId);
|
||||
self.childrenIds.replace(childrenIds);
|
||||
|
||||
self.disposed && dispose();
|
||||
},
|
||||
|
||||
dispose
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -68,12 +68,18 @@ export const RendererStore = types
|
|||
if (self.stores.has(store.id as string)) {
|
||||
return self.stores.get(store.id) as IIRendererStore;
|
||||
}
|
||||
|
||||
if (store.parentId) {
|
||||
const parent = self.stores.get(store.parentId) as IIRendererStore;
|
||||
parent.childrenIds.push(store.id);
|
||||
}
|
||||
|
||||
self.stores.put(store);
|
||||
return self.stores.get(store.id) as IIRendererStore;
|
||||
},
|
||||
|
||||
removeStore(store: IIRendererStore) {
|
||||
detach(store);
|
||||
store.dispose();
|
||||
}
|
||||
}));
|
||||
|
||||
|
|
Loading…
Reference in New Issue