Pick 一些优化 (#9073)

* chore: inputTable 中单元格数据没有差异时不触发变更

* fix: 修复 chrome 低版本列设置宽度无效的问题 (#9026)

* fix: 修复 patch 可能执行的问题

* perf: patch 逻辑改成批量处理提高性能

* chore: 优化列表点选功能,点选可以不用刷新整行
This commit is contained in:
liaoxuezhi 2023-12-08 11:48:29 +08:00 committed by GitHub
parent d0d4bda5ce
commit 7830e69e1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 113 additions and 27 deletions

View File

@ -206,11 +206,12 @@ export const Row = types
extendObject((getParent(self, self.depth * 2) as ITableStore).data, {
index: self.index,
// todo 以后再支持多层,目前先一层
parent: parent.storeType === Row.name ? parent.data : undefined,
parent: parent.storeType === Row.name ? parent.data : undefined
// 只有table时也可以获取选中行
selectedItems: table.selectedRows.map(item => item.data),
unSelectedItems: table.unSelectedRows.map(item => item.data)
// 行数据中不应该包含选中行,因为选中行是跨行的,不应该影响到行数据
// selectedItems: table.selectedRows.map(item => item.data),
// unSelectedItems: table.unSelectedRows.map(item => item.data)
}),
children
? {

View File

@ -0,0 +1,4 @@
export const chromeVersion = (function getChromeVersion() {
const raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
return raw ? parseInt(raw[2], 10) : false;
})();

View File

@ -1,6 +1,7 @@
export * from './api';
export * from './attachmentAdpator';
export * from './autobind';
export * from './browser';
export * from './ColorScale';
export * from './columnsSplit';
export * from './dataMapping';

View File

@ -65,6 +65,7 @@ import {VariableManager} from './variable';
import type {IScopedContext} from 'amis';
import type {SchemaObject, SchemaCollection} from 'amis';
import type {RendererConfig} from 'amis-core';
import {isAlive} from 'mobx-state-tree';
export interface EditorManagerConfig
extends Omit<EditorProps, 'value' | 'onChange'> {}
@ -1687,11 +1688,15 @@ export class EditorManager {
});
patching = false;
patchingInvalid = false;
patchSchema(force = false) {
if (this.patching) {
this.patchingInvalid = true;
return;
}
this.patching = true;
this.patchingInvalid = false;
const batch: Array<{id: string; value: any}> = [];
let patchList = (list: Array<EditorNodeType>) => {
// 深度优先
list.forEach((node: EditorNodeType) => {
@ -1699,14 +1704,18 @@ export class EditorManager {
patchList(node.uniqueChildren);
}
if (!node.isRegion) {
node.patch(this.store, force);
if (isAlive(node) && !node.isRegion) {
node.patch(this.store, force, (id, value) =>
batch.unshift({id, value})
);
}
});
};
patchList(this.store.root.children);
this.store.batchChangeValue(batch);
this.patching = false;
this.patchingInvalid && this.patchSchema(force);
}
/**

View File

@ -52,6 +52,7 @@ import {EditorManagerConfig} from '../manager';
import {EditorNode, EditorNodeType} from './node';
import findIndex from 'lodash/findIndex';
import {matchSorter} from 'match-sorter';
import debounce from 'lodash/debounce';
export interface SchemaHistory {
versionId: number;
@ -621,7 +622,7 @@ export const MainStore = types
return list.some(node => {
if (!node.patched && !node.isRegion) {
return true;
} else if (node.children.length) {
} else if (node.uniqueChildren.length) {
return hasUnPatched(node.children);
}
@ -1015,6 +1016,15 @@ export const MainStore = types
let doc: Document = document;
let iframe: HTMLIFrameElement | undefined = undefined;
const lazyUpdateTargetName = debounce(
() => (self as any).updateTargetName(),
250,
{
leading: false,
trailing: true
}
);
return {
setLayer(value: any) {
layer = value;
@ -1094,7 +1104,7 @@ export const MainStore = types
}
this.resetHistory();
this.updateTargetName();
lazyUpdateTargetName();
},
insertSchema(event: PluginEvent<InsertEventContext>) {
@ -1406,6 +1416,15 @@ export const MainStore = types
}
},
batchChangeValue(list: Array<{id: string; value: Schema}>) {
this.traceableSetSchema(
list.reduce((schema, item) => {
return JSONUpdate(schema, item.id, JSONPipeIn(item.value), true);
}, self.schema),
true
);
},
/**
* fixedabsolute
*/
@ -1776,7 +1795,7 @@ export const MainStore = types
schema: schema
});
self.schema = schema;
this.updateTargetName();
lazyUpdateTargetName();
},
undo() {
@ -1788,7 +1807,7 @@ export const MainStore = types
const version = self.schemaHistory[idx - 1];
self.versionId = version.versionId;
self.schema = version.schema;
this.updateTargetName();
lazyUpdateTargetName();
this.autoSelectRoot();
}
},
@ -1801,7 +1820,7 @@ export const MainStore = types
const version = self.schemaHistory[idx + 1];
self.versionId = version.versionId;
self.schema = version.schema;
this.updateTargetName();
lazyUpdateTargetName();
this.autoSelectRoot();
}
},
@ -1889,6 +1908,10 @@ export const MainStore = types
setAppCorpusData(data: any = {}) {
self.appCorpusData = data;
this.updateAppLocaleState();
},
beforeDestroy() {
lazyUpdateTargetName.cancel();
}
};
});

View File

@ -618,7 +618,11 @@ export const EditorNode = types
self.folded = !self.folded;
},
patch(store: any, force = false) {
patch(
store: any,
force = false,
setPatchInfo?: (id: string, value: any) => void
) {
// 避免重复 patch
if (self.patched && !force) {
return;
@ -664,13 +668,9 @@ export const EditorNode = types
) || patched;
if (patched !== schema) {
root.changeValueById(
info.id,
JSONPipeIn(patched),
undefined,
true,
true
);
setPatchInfo
? setPatchInfo(info.id, patched)
: root.changeValueById(info.id, patched, undefined, true, true);
}
},

View File

@ -339,15 +339,16 @@ export const HocQuickEdit =
onQuickChange(values, false, true);
}
handleChange(values: object) {
handleChange(values: object, diff?: any) {
const {onQuickChange, quickEdit} = this.props;
onQuickChange(
values,
(quickEdit as QuickEditConfig).saveImmediately,
false,
quickEdit as QuickEditConfig
);
Object.keys(diff).length &&
onQuickChange(
diff,
(quickEdit as QuickEditConfig).saveImmediately,
false,
quickEdit as QuickEditConfig
);
}
handleFormItemChange(value: any) {

View File

@ -10,6 +10,7 @@ import {
evalTrackExpression
} from 'amis-core';
import {BadgeObject, Checkbox, Icon} from 'amis-ui';
import {observer} from 'mobx-react';
import React from 'react';
export interface CellProps extends ThemeProps {
@ -34,7 +35,7 @@ export interface CellProps extends ThemeProps {
onImageEnlarge?: any;
}
export default function Cell({
export function Cell({
region,
column,
item,
@ -234,3 +235,5 @@ export default function Cell({
subProps
);
}
export default Cell;

View File

@ -1,5 +1,5 @@
import React from 'react';
import type {IColumn, ITableStore} from 'amis-core';
import {chromeVersion, type IColumn, type ITableStore} from 'amis-core';
import {observer} from 'mobx-react';
export function ColGroup({
@ -33,6 +33,50 @@ export function ColGroup({
};
}, []);
// 解决 chrome 91 以下版本的设置 colgroup>col 的 width 属性无效的问题
// 低版本同时设置 thead>th
// The problem is min-width CSS property.
// Before Chrome 91, min-width was ignored on COL elements. 91 no longer ignores it.
if (typeof chromeVersion === 'number' && chromeVersion < 91) {
React.useEffect(() => {
if (domRef.current) {
const ths = [].slice.call(
domRef.current.parentElement!.querySelectorAll(
':scope > thead > tr > th[data-index]'
)
);
ths.forEach((th: HTMLTableCellElement) => {
const index = parseInt(th.getAttribute('data-index')!, 10);
const column = store.columns[index];
let style = '';
let width: any = -1;
if (store.columnWidthReady && column.width) {
width = column.width;
} else if (column.pristine.width) {
width = column.pristine.width;
}
if (width === -1) {
return;
}
style += `width: ${
// 有可能是百分比
typeof width === 'number' ? `${width}px` : width
};`;
if (store.tableLayout === 'auto') {
style += `min-width: ${
typeof width === 'number' ? `${width}px` : width
};`;
}
th.style.cssText = style;
});
}
}, [columns.map(column => column.width).join(','), store.columnWidthReady]);
}
return (
<colgroup ref={domRef}>
{columns.map(column => {