diff --git a/src/renderers/Table/TableBody.tsx b/src/renderers/Table/TableBody.tsx new file mode 100644 index 000000000..060401644 --- /dev/null +++ b/src/renderers/Table/TableBody.tsx @@ -0,0 +1,196 @@ +import React from 'react'; +import {ClassNamesFn} from '../../theme'; +import {IColumn, IRow} from '../../store/table'; +import {SchemaNode, Action} from '../../types'; +import {TableRow} from './TableRow'; +import {filter} from '../../utils/tpl'; +import {observer} from 'mobx-react'; +import {trace, reaction} from 'mobx'; +import {flattenTree} from '../../utils/helper'; + +export interface TableBodyProps { + className?: string; + rowsProps?: any; + tableClassName?: string; + classnames: ClassNamesFn; + columns: Array; + rows: Array; + placeholder?: string; + render: (region: string, node: SchemaNode, props?: any) => JSX.Element; + renderCell: ( + region: string, + column: IColumn, + item: IRow, + props: any + ) => React.ReactNode; + onCheck: (item: IRow) => void; + onQuickChange?: ( + item: IRow, + values: object, + saveImmediately?: boolean | any, + savePristine?: boolean + ) => void; + footable?: boolean; + footableColumns: Array; + checkOnItemClick?: boolean; + buildItemProps?: (item: IRow, index: number) => any; + onAction?: (e: React.UIEvent, action: Action, ctx: object) => void; + rowClassNameExpr?: string; + rowClassName?: string; +} + +export class TableBody extends React.Component { + reaction?: () => void; + constructor(props: TableBodyProps) { + super(props); + + const rows = props.rows; + + this.reaction = reaction( + () => + `${flattenTree(rows) + .map(item => `${item.id}`) + .join(',')}${rows + .filter(item => item.checked) + .map(item => item.id) + .join(',')}`, + () => this.forceUpdate(), + { + onError: () => this.reaction!() + } + ); + } + + shouldComponentUpdate(nextProps: TableBodyProps) { + const props = this.props; + + if ( + props.columns !== nextProps.columns || + props.buildItemProps !== nextProps.buildItemProps + ) { + return true; + } + + return false; + } + + componentwillUnmount() { + this.reaction?.(); + } + + renderRows( + rows: Array, + columns = this.props.columns, + rowProps: any = {} + ): any { + const { + rowClassName, + rowClassNameExpr, + onAction, + buildItemProps, + checkOnItemClick, + classnames: cx, + render, + renderCell, + onCheck, + onQuickChange, + footable, + footableColumns + } = this.props; + + return rows.map((item: IRow, rowIndex: number) => { + const itemProps = buildItemProps ? buildItemProps(item, rowIndex) : null; + + const doms = [ + 1 && rowIndex === rows.length - 1 + } + )} + columns={columns} + renderCell={renderCell} + render={render} + onAction={onAction} + onCheck={onCheck} + // todo 先注释 quickEditEnabled={item.depth === 1} + onQuickChange={onQuickChange} + {...rowProps} + /> + ]; + + if (footable && footableColumns.length) { + if (item.depth === 1) { + doms.push( + + ); + } + } else if (item.children.length) { + // 嵌套表格 + doms.push( + ...this.renderRows(item.children, columns, { + ...rowProps, + parent: item + }) + ); + } + return doms; + }); + } + + render() { + const { + placeholder, + classnames: cx, + className, + render, + rows, + columns, + rowsProps + } = this.props; + + return ( + + {rows.length ? ( + this.renderRows(rows, columns, rowsProps) + ) : ( + + + {render('placeholder', placeholder || '暂无数据')} + + + )} + + ); + } +} diff --git a/src/renderers/Table/TableContent.tsx b/src/renderers/Table/TableContent.tsx index 18df72727..35479ddaf 100644 --- a/src/renderers/Table/TableContent.tsx +++ b/src/renderers/Table/TableContent.tsx @@ -7,6 +7,7 @@ import {filter} from '../../utils/tpl'; import {observer} from 'mobx-react'; import {trace, reaction} from 'mobx'; import {flattenTree} from '../../utils/helper'; +import {TableBody} from './TableBody'; export interface TableContentProps { className?: string; @@ -52,22 +53,6 @@ export class TableContent extends React.Component { reaction?: () => void; constructor(props: TableContentProps) { super(props); - - const rows = props.rows; - - this.reaction = reaction( - () => - `${flattenTree(rows) - .map(item => `${item.id}`) - .join(',')}${rows - .filter(item => item.checked) - .map(item => item.id) - .join(',')}`, - () => this.forceUpdate(), - { - onError: () => this.reaction!() - } - ); } shouldComponentUpdate(nextProps: TableContentProps) { @@ -83,100 +68,6 @@ export class TableContent extends React.Component { return false; } - componentwillUnmount() { - this.reaction?.(); - } - - renderRows( - rows: Array, - columns = this.props.columns, - rowProps: any = {} - ): any { - const { - rowClassName, - rowClassNameExpr, - onAction, - buildItemProps, - checkOnItemClick, - classnames: cx, - render, - renderCell, - onCheck, - onQuickChange, - footable, - footableColumns - } = this.props; - - return rows.map((item: IRow, rowIndex: number) => { - const itemProps = buildItemProps ? buildItemProps(item, rowIndex) : null; - - const doms = [ - 1 && rowIndex === rows.length - 1 - } - )} - columns={columns} - renderCell={renderCell} - render={render} - onAction={onAction} - onCheck={onCheck} - // todo 先注释 quickEditEnabled={item.depth === 1} - onQuickChange={onQuickChange} - {...rowProps} - /> - ]; - - if (footable && footableColumns.length) { - if (item.depth === 1) { - doms.push( - - ); - } - } else if (item.children.length) { - // 嵌套表格 - doms.push( - ...this.renderRows(item.children, columns, { - ...rowProps, - parent: item - }) - ); - } - return doms; - }); - } - render() { const { placeholder, @@ -189,7 +80,17 @@ export class TableContent extends React.Component { onScroll, tableRef, rows, - renderHeadCell + renderHeadCell, + renderCell, + onCheck, + rowClassName, + onQuickChange, + footable, + footableColumns, + checkOnItemClick, + buildItemProps, + onAction, + rowClassNameExpr } = this.props; const tableClassName = cx('Table-table', this.props.tableClassName); @@ -225,17 +126,23 @@ export class TableContent extends React.Component { )} - - {rows.length ? ( - this.renderRows(rows, columns) - ) : ( - - - {render('placeholder', placeholder || '暂无数据')} - - - )} - + ); diff --git a/src/renderers/Table/index.tsx b/src/renderers/Table/index.tsx index 80e2e8cd5..34b029e73 100644 --- a/src/renderers/Table/index.tsx +++ b/src/renderers/Table/index.tsx @@ -40,6 +40,7 @@ import {SchemaQuickEdit} from '../QuickEdit'; import {SchemaCopyable} from '../Copyable'; import {SchemaRemark} from '../Remark'; import {toDataURL, getImageDimensions} from '../../utils/image'; +import {TableBody} from './TableBody'; /** * 表格列,不指定类型时默认为文本类型。 @@ -1572,7 +1573,17 @@ export default class Table extends React.Component { headerOnly: boolean = false, tableClassName: string = '' ) { - const {placeholder, store, classnames: cx, render, data} = this.props; + const { + placeholder, + store, + classnames: cx, + render, + data, + checkOnItemClick, + buildItemProps, + rowClassNameExpr, + rowClassName + } = this.props; const hideHeader = store.filteredColumns.every(column => !column.label); return ( @@ -1612,25 +1623,36 @@ export default class Table extends React.Component { {headerOnly ? null : ( - - {rows.length ? ( - this.renderRows(rows, columns, { - regionPrefix: 'fixed/', - renderCell: ( - region: string, - column: IColumn, - item: IRow, - props: any - ) => this.renderCell(region, column, item, props, true) - }) - ) : ( - - - {render('placeholder', placeholder, {data})} - - + 0 ? 'Table-table--withCombine' : '', + tableClassName )} - + classnames={cx} + placeholder={placeholder} + render={render} + renderCell={this.renderCell} + onCheck={this.handleCheck} + onQuickChange={store.dragging ? undefined : this.handleQuickChange} + footable={store.footable} + footableColumns={store.footableColumns} + checkOnItemClick={checkOnItemClick} + buildItemProps={buildItemProps} + onAction={this.handleAction} + rowClassNameExpr={rowClassNameExpr} + rowClassName={rowClassName} + columns={columns} + rows={rows} + rowsProps={{ + regionPrefix: 'fixed/', + renderCell: ( + region: string, + column: IColumn, + item: IRow, + props: any + ) => this.renderCell(region, column, item, props, true) + }} + /> )} ); @@ -2085,93 +2107,6 @@ export default class Table extends React.Component { : footerNode || toolbarNode || null; } - renderRows( - rows: Array, - columns = this.props.store.filteredColumns, - rowProps: any = {} - ): any { - const { - store, - rowClassName, - rowClassNameExpr, - onAction, - buildItemProps, - checkOnItemClick, - classPrefix: ns, - classnames: cx, - render - } = this.props; - - return rows.map((item: IRow, rowIndex: number) => { - const itemProps = buildItemProps ? buildItemProps(item, rowIndex) : null; - - const doms = [ - 1 && rowIndex === rows.length - 1, - 'is-expanded': item.expanded, - 'is-expandable': item.expandable - } - )} - columns={columns} - renderCell={this.renderCell} - render={render} - onAction={onAction} - onCheck={this.handleCheck} - // todo 先注释 quickEditEnabled={item.depth === 1} - onQuickChange={store.dragging ? null : this.handleQuickChange} - {...rowProps} - /> - ]; - - if (store.footable && store.footableColumns.length) { - if (item.depth === 1) { - doms.push( - - ); - } - } else if (Array.isArray(item.data.children)) { - // 嵌套表格 - doms.push(...this.renderRows(item.children, columns, rowProps)); - } - - return doms; - }); - } - renderItemActions() { const {itemActions, render, store, classnames: cx} = this.props; const finalActions = Array.isArray(itemActions)