Merge pull request #6796 from hsm-lv/feat-context

feat:CRUD、Table上下文优化
This commit is contained in:
hsm-lv 2023-05-09 12:58:11 +08:00 committed by GitHub
commit 38d26ae414
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 485 additions and 136 deletions

View File

@ -183,13 +183,14 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
})
];
});
items = items.filter((item: any) => arrItems.find(a => a === item));
items = items.filter((item: any) =>
arrItems.find(a => a === item)
);
}
}
else {
} else {
items = matchSorter(items, value, {
keys: [key]
})
});
}
}
}
@ -349,11 +350,11 @@ export const CRUDStore = ServiceStore.named('CRUDStore')
})
];
});
filteredItems = filteredItems.filter(
item => arrItems.find(a => a === item));
filteredItems = filteredItems.filter(item =>
arrItems.find(a => a === item)
);
}
}
else {
} else {
filteredItems = matchSorter(filteredItems, value, {
keys: [key]
});

View File

@ -97,28 +97,97 @@ export class DataScope {
return false;
}
assignSchema(target: any, schema: any): any {
// key相同type也相同
if (target.type && target.type === schema.type) {
if (target.type === 'array') {
// 先只考虑items不考虑contains
if (target.items) {
if (Array.isArray(target.items)) {
if (schema.items) {
if (Array.isArray(schema.items)) {
// 如果都是数组,就后者覆盖前者
return schema.items;
} else {
// 否则,追加
return {
...target,
items: [...target.items, schema.items]
};
}
} else {
return {
...target,
...schema
};
}
} else {
// 非数组则merge
return {
...target,
items: this.assignSchema(target.items, schema.items)
};
}
} else {
return schema;
}
} else if (target.type === 'object' && target.properties) {
let properties: any = {};
// 合并属性
for (let key of Array.from(
new Set([
...Object.keys(target.properties),
...Object.keys(schema.properties)
])
)) {
const value = target.properties[key];
if (value) {
properties[key] = schema.properties[key]
? this.assignSchema(value, schema.properties[key])
: value;
} else {
properties[key] = schema.properties[key];
}
}
return {
...target,
properties
};
} else {
return schema;
}
} else {
// key相同、type不同
if (Array.isArray(target.oneOf)) {
return {
...target, // 先做个显示过度因formula还没支持oneOf
oneOf: [...target.oneOf, schema]
};
} else {
return {
...target, // 先做个显示过度因formula还没支持oneOf
oneOf: [target, schema]
};
}
}
}
getMergedSchema() {
const mergedSchema: any = {
type: 'object',
properties: {}
};
// todo 以后再来细化这一块,先粗略的写个大概
this.schemas.forEach(schema => {
const properties: any = schema.properties || {};
Object.keys(properties).forEach(key => {
const value = properties[key];
if (mergedSchema.properties[key]) {
if (Array.isArray(mergedSchema.properties[key].oneOf)) {
mergedSchema.properties[key].oneOf.push();
} else if (
mergedSchema.properties[key].type &&
mergedSchema.properties[key].type !== value.type
) {
mergedSchema.properties[key] = {
oneOf: [mergedSchema.properties[key], value]
};
}
mergedSchema.properties[key] = this.assignSchema(
mergedSchema.properties[key],
value
);
} else {
mergedSchema.properties[key] = value;
}
@ -132,19 +201,14 @@ export class DataScope {
options: Array<any>,
schema: JSONSchema,
path: string = '',
key: string = '',
/** 是否数组元素,数组元素的内容将获取每个成员的对应值 */
isArrayItem = false,
/** 不是所有的都可以选择,但不影响子元素 */
disabled?: boolean
key: string = ''
) {
// todo 支持 oneOf, anyOf
const option: any = {
label: schema.title || key,
value: path,
type: schema.type,
tag: schema.description ?? schema.type,
disabled
tag: schema.description ?? schema.type
};
options.push(option);
@ -155,43 +219,32 @@ export class DataScope {
keys.forEach(key => {
const child: any = schema.properties![key];
const newPath = isArrayItem ? `ARRAYMAP(${path}, item => item.${key})` : (path + (path ? '.' : '') + key);
this.buildOptions(
option.children,
child,
newPath,
key,
isArrayItem,
false
path + (path ? '.' : '') + key,
key
);
});
} else if (schema.type === 'array' && schema.items) {
option.children = [];
this.buildOptions(
option.children,
{
title: '成员',
...(schema.items as any)
},
path,
'items',
true,
true
);
this.buildOptions(
option.children,
{
title: '总数',
type: 'number'
title: '成员',
...(schema.items as any),
disabled: true
},
path + (path ? '.' : '') + 'length',
'length',
true,
isArrayItem
path,
'items'
);
option.children = mapTree(option.children, item => ({
...item,
disabled: true
}));
}
}
@ -219,4 +272,8 @@ export class DataScope {
}
return null;
}
getSchemaById(id: string) {
return this.schemas?.find(item => item.$id === id);
}
}

View File

@ -931,32 +931,40 @@ export function isObject(curObj: any) {
return isObject;
}
export function jsonToJsonSchema(json: any = {}) {
export function jsonToJsonSchema(
json: any = {},
titleBuilder?: (type: string, key: string) => string
) {
const jsonschema: any = {
type: 'object',
properties: {}
};
Object.keys(json).forEach(key => {
const value = json[key];
const type = typeof value;
const type = Array.isArray(value) ? 'array' : typeof value;
if (~['string', 'number'].indexOf(type)) {
jsonschema.properties[key] = {
type: type,
title: key
type,
title: titleBuilder?.(type, key) || key
};
} else if (type === 'object' && value) {
} else if (~['object', 'array'].indexOf(type) && value) {
jsonschema.properties[key] = {
type: 'object',
title: key
type,
title: titleBuilder?.(type, key) || key,
...(type === 'object'
? jsonToJsonSchema(value, titleBuilder)
: {items: jsonToJsonSchema(value[0], titleBuilder)})
};
} else {
jsonschema.properties[key] = {
type: '',
title: key
title: titleBuilder?.(type, key) || key
};
}
});
return jsonschema;
}

View File

@ -5,6 +5,7 @@ import React from 'react';
import {
getI18nEnabled,
jsonToJsonSchema,
registerEditorPlugin,
tipedLabel
} from 'amis-editor-core';
@ -23,13 +24,14 @@ import {
} from 'amis-editor-core';
import {defaultValue, getSchemaTpl} from 'amis-editor-core';
import {isObject, JSONPipeIn} from 'amis-editor-core';
import {setVariable} from 'amis-core';
import {setVariable, someTree} from 'amis-core';
import type {ActionSchema} from 'amis';
import type {CRUDCommonSchema} from 'amis';
import {getEnv} from 'mobx-state-tree';
import {EditorNodeType, RendererPluginAction} from 'amis-editor-core';
import type {EditorNodeType, RendererPluginAction} from 'amis-editor-core';
import {normalizeApi} from 'amis-core';
import isPlainObject from 'lodash/isPlainObject';
import omit from 'lodash/omit';
interface ColumnItem {
label: string;
@ -1745,7 +1747,92 @@ export class CRUDPlugin extends BasePlugin {
return;
}
return child.info.plugin.buildDataSchemas(child, undefined, trigger);
let childSchame = await child.info.plugin.buildDataSchemas(
child,
undefined,
trigger
);
// 兼容table的rows并自行merged异步数据
if (child.type === 'table') {
let cellProperties = {};
const columns: EditorNodeType = child.children.find(
item => item.isRegion && item.region === 'columns'
);
if (trigger) {
const isColumnChild = someTree(
columns?.children,
item => item.id === trigger.id
);
// merge异步数据中的单列成员因为rendererBeforeDispatchEvent无法区分是否需要单列成员
if (isColumnChild) {
const scope = this.manager.dataSchema.getScope(
`${node.id}-${node.type}`
);
const menberProps = (
scope.getSchemaById('crudFetchInitedData')?.properties?.items as any
)?.items?.properties;
cellProperties = {
...menberProps,
...omit(
childSchame.properties,
'rows',
'selectedItems',
'unSelectedItems'
)
};
}
}
childSchame = {
$id: childSchame.$id,
type: childSchame.type,
properties: {
...cellProperties,
items: childSchame.properties.rows,
selectedItems: childSchame.properties.selectedItems,
unSelectedItems: childSchame.properties.unSelectedItems,
count: {
type: 'number',
title: '总行数'
},
page: {
type: 'number',
title: '当前页码'
}
}
};
}
return childSchame;
}
rendererBeforeDispatchEvent(node: EditorNodeType, e: any, data: any) {
if (e === 'fetchInited') {
const scope = this.manager.dataSchema.getScope(`${node.id}-${node.type}`);
const jsonschema: any = {
$id: 'crudFetchInitedData',
type: 'object',
...jsonToJsonSchema(
omit(data, 'selectedItems', 'unSelectedItems'),
(type: string, key: string) => {
if (type === 'array' && key === 'items') {
return '数据列表';
}
if (type === 'number' && key === 'count') {
return '总行数';
}
return key;
}
)
};
scope?.removeSchema(jsonschema.$id);
scope?.addSchema(jsonschema);
}
}
/** crud 不同 mode 之间转换时候,主体的转换 */

View File

@ -68,13 +68,13 @@ export class ServicePlugin extends BasePlugin {
},
{
eventName: 'fetchInited',
eventLabel: '初始化数据接口请求',
description: '远程初始化数据接口请求时触发'
eventLabel: '初始化数据接口请求成',
description: '远程初始化数据接口请求成时触发'
},
{
eventName: 'fetchSchemaInited',
eventLabel: '初始化Schema接口请求',
description: '远程初始化Schema接口请求时触发'
eventLabel: '初始化Schema接口请求成',
description: '远程初始化Schema接口请求成时触发'
}
];

View File

@ -27,7 +27,11 @@ import {
getEventControlConfig,
getArgsWrapper
} from '../renderer/event-control/helper';
import {schemaArrayFormat, schemaToArray, resolveArrayDatasource} from '../util';
import {
schemaArrayFormat,
schemaToArray,
resolveArrayDatasource
} from '../util';
export class TablePlugin extends BasePlugin {
// 关联渲染器名字
@ -289,7 +293,51 @@ export class TablePlugin extends BasePlugin {
properties: {
'event.data.item': {
type: 'object',
title: '行点击数据'
title: '当前行数据'
},
'event.data.index': {
type: 'number',
title: '当前行索引'
}
}
}
]
},
{
eventName: 'rowMouseEnter',
eventLabel: '鼠标移入行事件',
description: '移入整行时触发',
dataSchema: [
{
type: 'object',
properties: {
'event.data.item': {
type: 'object',
title: '当前行数据'
},
'event.data.index': {
type: 'number',
title: '当前行索引'
}
}
}
]
},
{
eventName: 'rowMouseLeave',
eventLabel: '鼠标移出行事件',
description: '移出整行时触发',
dataSchema: [
{
type: 'object',
properties: {
'event.data.item': {
type: 'object',
title: '当前行数据'
},
'event.data.index': {
type: 'number',
title: '当前行索引'
}
}
}
@ -680,16 +728,28 @@ export class TablePlugin extends BasePlugin {
item => item.isRegion && item.region === 'columns'
);
for (let current of columns?.children) {
const schema = current.schema;
if (schema.name) {
itemsSchema.properties[schema.name] = current.info?.plugin
?.buildDataSchemas
? await current.info.plugin.buildDataSchemas(current, region)
: {
type: 'string',
title: schema.label || schema.name
};
// todo以下的处理无效需要cell实现才能深层细化
// for (let current of columns?.children) {
// const schema = current.schema;
// if (schema.name) {
// itemsSchema.properties[schema.name] = current.info?.plugin
// ?.buildDataSchemas
// ? await current.info.plugin.buildDataSchemas(current, region)
// : {
// type: 'string',
// title: schema.label || schema.name
// };
// }
// }
// 一期先简单处理上面todo实现之后这里可以废弃
// table 无法根据source确定异步数据来源因此不能在table层做异步数据列的收集
for (let current of node.schema?.columns) {
if (current.name) {
itemsSchema.properties[current.name] = {
type: 'string',
title: current.label || current.name
};
}
}
@ -716,6 +776,16 @@ export class TablePlugin extends BasePlugin {
type: 'array',
title: '数据列表',
items: itemsSchema
},
selectedItems: {
type: 'array',
title: '已选中行'
// items: itemsSchema
},
unSelectedItems: {
type: 'array',
title: '未选中行'
// items: itemsSchema
}
}
};

View File

@ -775,7 +775,7 @@ export default class CRUD extends React.Component<CRUDProps, any> {
const ctx = createObject(store.mergedData, {
...selectedItems[0],
currentPageData: store.mergedData.items.concat(),
currentPageData: (store.mergedData?.items || []).concat(),
rows: selectedItems,
items: selectedItems,
selectedItems,
@ -865,7 +865,8 @@ export default class CRUD extends React.Component<CRUDProps, any> {
},
false,
true,
this.props.initFetch !== false
this.props.initFetch !== false,
true
);
store.setPristineQuery();
@ -910,7 +911,8 @@ export default class CRUD extends React.Component<CRUDProps, any> {
values: Record<string, any>,
jumpToFirstPage: boolean = true,
replaceLocation: boolean = false,
search: boolean = true
search: boolean = true,
isInit: boolean = false
) {
const {
store,
@ -942,8 +944,15 @@ export default class CRUD extends React.Component<CRUDProps, any> {
perPageField
);
this.lastQuery = store.query;
search &&
this.search(undefined, undefined, undefined, loadDataOnceFetchOnFilter);
this.search(
undefined,
undefined,
undefined,
loadDataOnceFetchOnFilter,
isInit
);
}
handleBulkGo(
@ -1110,7 +1119,8 @@ export default class CRUD extends React.Component<CRUDProps, any> {
values?: any,
silent?: boolean,
clearSelection?: boolean,
forceReload = false
forceReload = false,
isInit: boolean = false
) {
const {
store,
@ -1130,7 +1140,8 @@ export default class CRUD extends React.Component<CRUDProps, any> {
loadDataOnce,
loadDataOnceFetchOnFilter,
source,
columns
columns,
dispatchEvent
} = this.props;
// reload 需要清空用户选择。
@ -1175,7 +1186,26 @@ export default class CRUD extends React.Component<CRUDProps, any> {
columns: store.columns ?? columns
})
.then(value => {
const {page, lastPage} = store;
const {page, lastPage, data, error, msg} = store;
if (isInit) {
// 初始化请求完成
const rendererEvent = dispatchEvent?.(
'fetchInited',
createObject(this.props.data, {
...data,
__response: {
error,
msg
}
})
);
if (rendererEvent?.prevented) {
return;
}
}
// 空列表 且 页数已经非法超出,则跳转到最后的合法页数
if (
!store.data.items.length &&
@ -1537,8 +1567,8 @@ export default class CRUD extends React.Component<CRUDProps, any> {
newItems.splice(0, newItems.length - 1)
);
}
store.setSelectedItems(newItems);
store.setUnSelectedItems(newUnSelectedItems);
store.updateSelectData(newItems, newUnSelectedItems);
onSelect && onSelect(newItems, newUnSelectedItems);
}
@ -1701,7 +1731,6 @@ export default class CRUD extends React.Component<CRUDProps, any> {
let bulkBtns: Array<ActionSchema> = [];
let itemBtns: Array<ActionSchema> = [];
const ctx = createObject(store.mergedData, {
currentPageData: (store.mergedData?.items || []).concat(),
rows: selectedItems.concat(),
@ -2414,4 +2443,13 @@ export class CRUDRenderer extends CRUD {
const scoped = this.context as IScopedContext;
scoped.close(target);
}
setData(values: object, replace?: boolean) {
return this.props.store.updateData(values, undefined, replace);
}
getData() {
const {store, data} = this.props;
return store.getData(data);
}
}

View File

@ -910,6 +910,7 @@ export default class CRUD2 extends React.Component<CRUD2Props, any> {
);
}
store.updateSelectData(newItems, newUnSelectedItems);
onSelect && onSelect(newItems);
}

View File

@ -512,10 +512,13 @@ export default class Service extends React.Component<ServiceProps> {
const data = result?.hasOwnProperty('ok') ? result.data ?? {} : result;
const {onBulkChange, dispatchEvent, store} = this.props;
dispatchEvent?.('fetchInited', {
...data,
__response: {msg: store.msg, error: store.error}
});
dispatchEvent?.(
'fetchInited',
createObject(this.props.data, {
...data,
__response: {msg: store.msg, error: store.error}
})
);
if (!isEmpty(data) && onBulkChange) {
onBulkChange(data);

View File

@ -1,5 +1,5 @@
import React from 'react';
import {ClassNamesFn} from 'amis-core';
import {ClassNamesFn, RendererEvent} from 'amis-core';
import {SchemaNode, ActionObject} from 'amis-core';
import {TableRow} from './TableRow';
@ -26,6 +26,15 @@ export interface TableBodyProps extends LocaleProps {
props: any
) => React.ReactNode;
onCheck: (item: IRow, value: boolean, shift?: boolean) => void;
onRowClick: (item: IRow, index: number) => Promise<RendererEvent<any> | void>;
onRowMouseEnter: (
item: IRow,
index: number
) => Promise<RendererEvent<any> | void>;
onRowMouseLeave: (
item: IRow,
index: number
) => Promise<RendererEvent<any> | void>;
onQuickChange?: (
item: IRow,
values: object,
@ -69,12 +78,14 @@ export class TableBody extends React.Component<TableBodyProps> {
footable,
ignoreFootableContent,
footableColumns,
itemAction
itemAction,
onRowClick,
onRowMouseEnter,
onRowMouseLeave
} = this.props;
return rows.map((item: IRow, rowIndex: number) => {
const itemProps = buildItemProps ? buildItemProps(item, rowIndex) : null;
const doms = [
<TableRow
{...itemProps}
@ -99,6 +110,9 @@ export class TableBody extends React.Component<TableBodyProps> {
onCheck={onCheck}
// todo 先注释 quickEditEnabled={item.depth === 1}
onQuickChange={onQuickChange}
onRowClick={onRowClick}
onRowMouseEnter={onRowMouseEnter}
onRowMouseLeave={onRowMouseLeave}
{...rowProps}
/>
];
@ -124,6 +138,9 @@ export class TableBody extends React.Component<TableBodyProps> {
render={render}
onAction={onAction}
onCheck={onCheck}
onRowClick={onRowClick}
onRowMouseEnter={onRowMouseEnter}
onRowMouseLeave={onRowMouseLeave}
footableMode
footableColSpan={columns.length}
onQuickChange={onQuickChange}

View File

@ -5,7 +5,8 @@ import {
SchemaNode,
ActionObject,
LocaleProps,
OnEventProps
OnEventProps,
RendererEvent
} from 'amis-core';
import {TableBody} from './TableBody';
import {observer} from 'mobx-react';
@ -42,6 +43,15 @@ export interface TableContentProps extends LocaleProps {
props: any
) => React.ReactNode;
onCheck: (item: IRow, value: boolean, shift?: boolean) => void;
onRowClick: (item: IRow, index: number) => Promise<RendererEvent<any> | void>;
onRowMouseEnter: (
item: IRow,
index: number
) => Promise<RendererEvent<any> | void>;
onRowMouseLeave: (
item: IRow,
index: number
) => Promise<RendererEvent<any> | void>;
onQuickChange?: (
item: IRow,
values: object,
@ -128,6 +138,9 @@ export class TableContent extends React.Component<TableContentProps> {
renderHeadCell,
renderCell,
onCheck,
onRowClick,
onRowMouseEnter,
onRowMouseLeave,
rowClassName,
onQuickChange,
footable,
@ -233,6 +246,9 @@ export class TableContent extends React.Component<TableContentProps> {
render={render}
renderCell={renderCell}
onCheck={onCheck}
onRowClick={onRowClick}
onRowMouseEnter={onRowMouseEnter}
onRowMouseLeave={onRowMouseLeave}
onQuickChange={onQuickChange}
footable={footable}
footableColumns={footableColumns}

View File

@ -1,12 +1,21 @@
import {observer} from 'mobx-react';
import React from 'react';
import type {IColumn, IRow} from 'amis-core';
import {RendererProps} from 'amis-core';
import type {IColumn, IRow} from 'amis-core/lib/store/table';
import {RendererEvent, RendererProps} from 'amis-core';
import {Action} from '../Action';
import {isClickOnInput, createObject} from 'amis-core';
interface TableRowProps extends Pick<RendererProps, 'render'> {
onCheck: (item: IRow) => Promise<void>;
onRowClick: (item: IRow, index: number) => Promise<RendererEvent<any> | void>;
onRowMouseEnter: (
item: IRow,
index: number
) => Promise<RendererEvent<any> | void>;
onRowMouseLeave: (
item: IRow,
index: number
) => Promise<RendererEvent<any> | void>;
classPrefix: string;
renderCell: (
region: string,
@ -39,26 +48,13 @@ export class TableRow extends React.Component<TableRowProps> {
}
handleMouseEnter(e: React.MouseEvent<HTMLTableRowElement>) {
const {item, itemIndex, data, dispatchEvent} = this.props;
dispatchEvent(
'rowMouseEnter',
createObject(data, {
item: item?.data,
index: itemIndex
})
);
const {item, itemIndex, onRowMouseEnter} = this.props;
onRowMouseEnter?.(item?.data, itemIndex);
}
handleMouseLeave(e: React.MouseEvent<HTMLTableRowElement>) {
const {item, itemIndex, data, dispatchEvent} = this.props;
dispatchEvent(
'rowMouseLeave',
createObject(data, {
item: item?.data,
index: itemIndex
})
);
const {item, itemIndex, onRowMouseLeave} = this.props;
onRowMouseLeave?.(item?.data, itemIndex);
}
// 定义点击一行的行为,通过 itemAction配置
@ -70,24 +66,10 @@ export class TableRow extends React.Component<TableRowProps> {
e.preventDefault();
e.stopPropagation();
const {
itemAction,
onAction,
item,
itemIndex,
data,
dispatchEvent,
onCheck
} = this.props;
const {itemAction, onAction, item, itemIndex, onCheck, onRowClick} =
this.props;
const rendererEvent = await dispatchEvent(
'rowClick',
createObject(data, {
rowItem: item?.data, // 保留rowItem 可能有用户已经在用 兼容之前的版本
item: item?.data,
index: itemIndex
})
);
const rendererEvent = await onRowClick?.(item?.data, itemIndex);
if (rendererEvent?.prevented) {
return;

View File

@ -1,7 +1,12 @@
import React from 'react';
import {findDOMNode} from 'react-dom';
import isEqual from 'lodash/isEqual';
import {ScopedContext, IScopedContext, SchemaExpression} from 'amis-core';
import {
ScopedContext,
IScopedContext,
SchemaExpression,
extendObject
} from 'amis-core';
import {Renderer, RendererProps} from 'amis-core';
import {SchemaNode, ActionObject, Schema} from 'amis-core';
import forEach from 'lodash/forEach';
@ -547,6 +552,9 @@ export default class Table extends React.Component<TableProps, object> {
this.handleMouseLeave = this.handleMouseLeave.bind(this);
this.subFormRef = this.subFormRef.bind(this);
this.handleColumnToggle = this.handleColumnToggle.bind(this);
this.handleRowClick = this.handleRowClick.bind(this);
this.handleRowMouseEnter = this.handleRowMouseEnter.bind(this);
this.handleRowMouseLeave = this.handleRowMouseLeave.bind(this);
this.updateAutoFillHeight = this.updateAutoFillHeight.bind(this);
@ -910,16 +918,51 @@ export default class Table extends React.Component<TableProps, object> {
this.syncSelected();
}
handleRowClick(item: IRow, index: number) {
const {dispatchEvent, store, data} = this.props;
return dispatchEvent(
'rowClick',
createObject(data, {
rowItem: item, // 保留rowItem 可能有用户已经在用 兼容之前的版本
item,
index
})
);
}
handleRowMouseEnter(item: IRow, index: number) {
const {dispatchEvent, store, data} = this.props;
return dispatchEvent(
'rowMouseEnter',
createObject(data, {
item,
index
})
);
}
handleRowMouseLeave(item: IRow, index: number) {
const {dispatchEvent, store, data} = this.props;
return dispatchEvent(
'rowMouseLeave',
createObject(data, {
item,
index
})
);
}
async handleCheckAll() {
const {store, data, dispatchEvent} = this.props;
const items = store.getSelectedRows().map(item => item.data);
const items = store.rows.map((row: any) => row.data);
const selectedItems = store.getSelectedRows().map(item => item.data);
const rendererEvent = await dispatchEvent(
'selectedChange',
createObject(data, {
selectedItems: store.allChecked ? [] : items,
unSelectedItems: store.allChecked ? items : []
selectedItems: store.allChecked ? [] : selectedItems,
unSelectedItems: store.allChecked ? selectedItems : [],
items
})
);
@ -2236,7 +2279,13 @@ export default class Table extends React.Component<TableProps, object> {
// 操作列不下发loading否则会导致操作栏里面的所有按钮都出现loading
loading: column.type === 'operation' ? false : props.loading,
btnDisabled: store.dragging,
data: item.locals,
data: this.props.selectable
? extendObject(item.locals, {
// 只有table时也可以获取选中行
selectedItems: store.selectedRows.map(item => item.data),
unSelectedItems: store.unSelectedRows.map(item => item.data)
})
: item.locals,
value: column.name
? resolveVariable(
column.name,
@ -2430,6 +2479,9 @@ export default class Table extends React.Component<TableProps, object> {
render={render}
renderCell={this.renderCell}
onCheck={this.handleCheck}
onRowClick={this.handleRowClick}
onRowMouseEnter={this.handleRowMouseEnter}
onRowMouseLeave={this.handleRowMouseLeave}
onQuickChange={store.dragging ? undefined : this.handleQuickChange}
footable={store.footable}
ignoreFootableContent
@ -2817,6 +2869,7 @@ export default class Table extends React.Component<TableProps, object> {
{
...this.props,
selectedItems: store.selectedRows.map(item => item.data),
unSelectedItems: store.unSelectedRows.map(item => item.data),
items: store.rows.map(item => item.data)
},
this.renderToolbar
@ -2916,6 +2969,9 @@ export default class Table extends React.Component<TableProps, object> {
renderHeadCell={this.renderHeadCell}
renderCell={this.renderCell}
onCheck={this.handleCheck}
onRowClick={this.handleRowClick}
onRowMouseEnter={this.handleRowMouseEnter}
onRowMouseLeave={this.handleRowMouseLeave}
onQuickChange={store.dragging ? undefined : this.handleQuickChange}
footable={store.footable}
footableColumns={store.footableColumns}
@ -3091,6 +3147,19 @@ export class TableRenderer extends Table {
return scoped.reload(subPath, ctx);
}
}
setData(values: any, replace?: boolean) {
const data = {
...values,
rows: values.rows ?? values.items // 做个兼容
};
return this.props.store.updateData(data, undefined, replace);
}
getData() {
const {store, data} = this.props;
return store.getData(data);
}
}
export {TableCell};