mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-02 03:58:07 +08:00
fix: Picker组件卡死问题
This commit is contained in:
parent
f24ea38408
commit
6893bd25f9
@ -515,7 +515,7 @@ 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` | 点击时触发 |
|
||||
| 事件名称 | 事件参数 | 说明 |
|
||||
| --------- | ------------------------------------------------------------------ | ---------------- |
|
||||
| change | `event.data.value: string`<br/> `event.data.option: Option` 选中值 | 选中值变化时触发 |
|
||||
| itemclick | `event.data.label: string`<br/> `event.data.id: string` | 点击时触发 |
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
@ -281,7 +281,6 @@ export default class PickerControl extends React.PureComponent<
|
||||
additionalOptions.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
additionalOptions.length && setOptions(options.concat(additionalOptions));
|
||||
const rendererEvent = await dispatchEvent(
|
||||
@ -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(
|
||||
const rendererEvent = await dispatchEvent(
|
||||
'itemclick',
|
||||
createObject(data, {'label': itemlabel, 'id': itemid})
|
||||
createObject(data, {label: itemlabel, id: itemid})
|
||||
);
|
||||
if (rendererEvent?.prevented) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
removeItem(index: number) {
|
||||
@ -413,11 +406,14 @@ export default class PickerControl extends React.PureComponent<
|
||||
>
|
||||
×
|
||||
</span>
|
||||
<span
|
||||
<span
|
||||
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 ? (
|
||||
|
@ -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}
|
||||
|
Loading…
Reference in New Issue
Block a user