fix: Picker组件卡死问题

This commit is contained in:
lurunze1226 2022-10-10 21:46:32 +08:00
parent f24ea38408
commit 6893bd25f9
4 changed files with 50 additions and 43 deletions

View File

@ -516,6 +516,6 @@ order: 35
当前组件会对外派发以下事件,可以通过`onEvent`来监听这些事件,并通过`actions`来配置执行的动作,在`actions`中可以通过`event.data.xxx`事件参数变量来获取事件产生的数据,详细请查看[事件动作](../../docs/concepts/event-action)。
| 事件名称 | 事件参数 | 说明 |
| -------- | ------------------------------------------------------------------ | ---------------- |
| --------- | ------------------------------------------------------------------ | ---------------- |
| change | `event.data.value: string`<br/> `event.data.option: Option` 选中值 | 选中值变化时触发 |
| itemclick | `event.data.label: string`<br/> `event.data.id: string` | 点击时触发 |

View File

@ -1,5 +1,5 @@
import React from 'react';
import isEqual from 'lodash/isEqual';
import {Renderer, RendererProps} from 'amis-core';
import {SchemaNode, Schema, ActionObject, PlainObject} from 'amis-core';
import {CRUDStore, ICRUDStore} from 'amis-core';
@ -519,13 +519,19 @@ export default class CRUD extends React.Component<CRUDProps, any> {
}
let val: any;
if (
this.props.pickerMode &&
isArrayChildrenModified(
(val = getPropValue(this.props)),
getPropValue(prevProps)
)
) &&
!isEqual(val, store.selectedItems.concat())
) {
/**
* Table -> CRUD -> Picker -> Form
* Picker模式来说store.selectedItems已经更新过了
*/
store.setSelectedItems(val);
}
@ -1469,6 +1475,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
newItems.splice(0, newItems.length - 1)
);
}
store.setSelectedItems(newItems);
store.setUnSelectedItems(newUnSelectedItems);
onSelect && onSelect(newItems);

View File

@ -1,30 +1,28 @@
import React from 'react';
import cx from 'classnames';
import omit from 'lodash/omit';
import find from 'lodash/find';
import isEqual from 'lodash/isEqual';
import findIndex from 'lodash/findIndex';
import {
OptionsControl,
OptionsControlProps,
Option,
FormOptionsControl
} from 'amis-core';
import cx from 'classnames';
import {SchemaNode, Schema, ActionObject, PlainObject} from 'amis-core';
import find from 'lodash/find';
import {
anyChanged,
SchemaNode,
Schema,
ActionObject,
PlainObject,
autobind,
getVariable,
noop,
createObject,
isObjectShallowModified
filter,
isPureVariable,
resolveVariableAndFilter,
isApiOutdated,
isEffectiveApi
} from 'amis-core';
import findIndex from 'lodash/findIndex';
import {Html} from 'amis-ui';
import {filter} from 'amis-core';
import {Icon} from 'amis-ui';
import {dataMapping, isPureVariable, resolveVariableAndFilter} from 'amis-core';
import {FormOptionsSchema, SchemaCollection, SchemaTpl} from '../../Schema';
import {CRUDSchema} from '../CRUD';
import {isApiOutdated, isEffectiveApi} from 'amis-core';
import {Html, Icon} from 'amis-ui';
import {FormOptionsSchema, SchemaTpl} from '../../Schema';
/**
* Picker
@ -124,8 +122,9 @@ export default class PickerControl extends React.PureComponent<
componentDidUpdate(prevProps: PickerProps) {
const props = this.props;
const detectedProps = ['multiple', 'source', 'pickerSchema'];
if (anyChanged(['pickerSchema', 'multiple', 'source'], prevProps, props)) {
if (detectedProps.some(key => !isEqual(prevProps[key], props[key]))) {
this.setState({
schema: this.buildSchema(props)
});
@ -227,7 +226,7 @@ export default class PickerControl extends React.PureComponent<
}
@autobind
handleModalConfirm(
async handleModalConfirm(
values: Array<any>,
action: ActionObject,
ctx: any,
@ -237,7 +236,8 @@ export default class PickerControl extends React.PureComponent<
components,
(item: any) => item.props.type === 'crud'
);
this.handleChange(values[idx].items);
await this.handleChange(values[idx].items);
this.close();
}
@ -252,10 +252,10 @@ export default class PickerControl extends React.PureComponent<
options,
data,
dispatchEvent,
selectedOptions,
setOptions,
onChange
} = this.props;
let value: any = items;
if (joinValues) {
@ -282,7 +282,6 @@ export default class PickerControl extends React.PureComponent<
}
});
additionalOptions.length && setOptions(options.concat(additionalOptions));
const rendererEvent = await dispatchEvent(
'change',
@ -295,23 +294,17 @@ export default class PickerControl extends React.PureComponent<
onChange(value);
}
@autobind
async handleItemClick(itemlabel: string, itemid: string) {
const {
data,
dispatchEvent,
setOptions
} = this.props;
const {data, dispatchEvent, setOptions} = this.props;
const rendererEvent = await dispatchEvent(
'itemclick',
createObject(data, {'label': itemlabel, 'id': itemid})
createObject(data, {label: itemlabel, id: itemid})
);
if (rendererEvent?.prevented) {
return;
}
}
removeItem(index: number) {
@ -417,7 +410,10 @@ export default class PickerControl extends React.PureComponent<
className={`${ns}Picker-valueLabel`}
onClick={e => {
e.stopPropagation();
this.handleItemClick(getVariable(item, labelField || 'label'), getVariable(item, 'id')|| '');
this.handleItemClick(
getVariable(item, labelField || 'label'),
getVariable(item, 'id') || ''
);
}}
>
{labelTpl ? (
@ -468,16 +464,15 @@ export default class PickerControl extends React.PureComponent<
modalMode,
source,
size,
env,
clearable,
multiple,
placeholder,
embed,
value,
selectedOptions,
translate: __,
popOverContainer
} = this.props;
return (
<div className={cx(`PickerControl`, className)}>
{embed ? (

View File

@ -1,5 +1,6 @@
import React from 'react';
import {findDOMNode} from 'react-dom';
import isEqual from 'lodash/isEqual';
import {ScopedContext, IScopedContext, SchemaExpression} from 'amis-core';
import {Renderer, RendererProps} from 'amis-core';
import {SchemaNode, ActionObject, Schema} from 'amis-core';
@ -602,9 +603,10 @@ export default class Table extends React.Component<TableProps, object> {
let rows: Array<object> = [];
let updateRows = false;
// 要严格比较前后的value值否则某些情况下会导致循环update无限渲染
if (
Array.isArray(value) &&
(!prevProps || (prevProps.value || prevProps.items) !== value)
(!prevProps || !isEqual(prevProps.value || prevProps.items, value))
) {
updateRows = true;
rows = value;
@ -1912,6 +1914,7 @@ export default class Table extends React.Component<TableProps, object> {
if (column.searchable && column.name && !autoGenerateFilter) {
affix.push(
<HeadCellSearchDropDown
key="table-head-search"
{...this.props}
onQuery={onQuery}
name={column.name}
@ -1928,6 +1931,7 @@ export default class Table extends React.Component<TableProps, object> {
if (column.sortable && column.name) {
affix.push(
<span
key="table-head-sort"
className={cx('TableCell-sortBtn')}
onClick={async () => {
let orderBy = '';
@ -1998,6 +2002,7 @@ export default class Table extends React.Component<TableProps, object> {
if (!column.searchable && column.filterable && column.name) {
affix.push(
<HeadCellFilterDropDown
key="table-head-filter"
{...this.props}
onQuery={onQuery}
name={column.name}