通用工具函数
ali-react-table
导出的通用工具函数
applyTransforms
#
deprecated
表格功能拓展(transforms) 已经过时,API 也不应被使用了。
API: function applyTransforms<T>(input: T, ...transforms: Transform<T>[]): T
以 input 作为输入,按序使用 transform。transform 是一个简单的纯函数,transform 的参数类型与返回值类型相同
applyTransforms(input, f1, f2, f3)
等价于 f3(f2(f1(input)))
.
// 相关源码参考type Transform<T> = (input: T) => T
function applyTransforms<T>(input: T, ...transforms: Transform<T>[]) { return transforms.reduce((v, fn) => fn(v), input)}
buildTree
#
API: function buildTree<T>(idProp: string, parentIdProp: string, items: T[]): WithChildren<T>[]
根据 idProp
与 parentIdProp
从平铺的对象数组中构建对应的树;
- 当
A[parentIdProp] === B[idProp]
时,对象 A 会被移动到对象 B 的 children 字段中; - 当一个对象的
parentIdProp
不与其他对象的idProp
字段相等时,该对象被作为树的顶层节点。
const array = [ { id: 'node-1', parent: 'root', name: '我是节点1' }, { id: 'node-2', parent: 'root', name: '我是节点2' }, { id: 'node-3', parent: 'node-2', name: '我是节点3' }, { id: 'node-4', parent: 'node-2', name: '我是节点4' }, { id: 'node-5', parent: 'node-4', name: '我是节点5' },]
const tree = buildTree('id', 'parent', array)
expect(tree).toEqual([ { id: 'node-1', parent: 'root', name: '我是节点1' }, { id: 'node-2', parent: 'root', name: '我是节点2', children: [ { id: 'node-3', parent: 'node-2', name: '我是节点3' }, { id: 'node-4', parent: 'node-2', name: '我是节点4', children: [{ id: 'node-5', parent: 'node-3', name: '我是节点5' }], }, ], },])
collectNodes
#
收集一棵树上的节点
API: function collectNodes<T extends AbstractTreeNode>(nodes: T[], order: 'pre' | 'post' | 'leaf-only'): T[]
- pre: 前序遍历
- post: 后续遍历
- leaf-only: 仅收集叶子节点
const tree = [ { id: 'node-1', parent: 'root', name: '我是节点1' }, { id: 'node-2', parent: 'root', name: '我是节点2', children: [ { id: 'node-3', parent: 'node-2', name: '我是节点3' }, { id: 'node-4', parent: 'node-2', name: '我是节点4', children: [{ id: 'node-5', parent: 'node-3', name: '我是节点5' }], }, ], },]
const result = collectNodes(tree, 'pre')
expect(result).toEqual([ { id: 'node-1', parent: 'root', name: '我是节点1' }, { id: 'node-2', parent: 'root', name: '我是节点2', children: [ { id: 'node-3', ...others }, { id: 'node-4', ...others }, ], }, { id: 'node-3', parent: 'node-2', name: '我是节点3' }, { id: 'node-4', parent: 'node-2', name: '我是节点4', ...others }, { id: 'node-5', parent: 'node-3', name: '我是节点5' },])
exportTableAsExcel
#
将表格数据导出为 Excel 文件。
function exportTableAsExcel( // 一般情况下为 xlsxPackage 参数传入 require('xlsx') 即可 xlsxPackage: typeof XLSX_NS, dataSource: any[], columns: ArtColumn[], filename: string,): void
「表格导出」与「表格渲染」的不同点:
- 单元格内容:
- BaseTable 渲染时,会使用
column.render
来渲染单元格中的内容 - exportTableAsExcel 只会使用
column.code
或是column.getValue
来获取表格中每个单元格的内容
- BaseTable 渲染时,会使用
- 列隐藏:
- 当
column.hidden
为 true 时,BaseTable 会隐藏相应的列 - exportTableAsExcel 总是会导出所有的列
- 当
- 支持的表格特性:
- BaseTable 支持所有表格特性
- 表格导出仅支持一部分表格特性:
- 支持 表头分组
- 支持 单元格合并
- 不支持 单元格样式
getTreeDepth
#
API: function getTreeDepth(nodes: AbstractTreeNode[]): number
获取一棵树的高度/深度
groupBy
#
API: function groupBy<T, K extends string>(list: T[], iteratee: (t: T) => K): { [key in K]: T[] }
对 list 中的元素进行分组,iteratee 的返回值相同的元素将被分到同一个分组。
groupBy2
#
API: function groupBy2<T, K extends string | number>(list: T[], iteratee: (t: T) => K): Map<K, T>
与 groupBy 作用相同,但会使用 Map 作为返回结果,并尽量保持数据的原始顺序。
isLeafNode
#
判断一个节点是否为叶子节点
// 相关源码参考interface AbstractTreeNode { children?: AbstractTreeNode[]}
function isLeafNode<N extends AbstractTreeNode>(node: N) { return node.children == null || node.children.length === 0}
layeredSort
#
API: function layeredSort<T extends AbstractTreeNode>(array: T[], compare: (x: T, y: T) => number): T[]
对树状结构的数据进行排序。
layeredSort
与 Array#sort
类似。但 layeredSort 是一个递归的过程,针对树上的每一个父节点,该函数都会对其子节点数组(children) 进行排序.
mergeCellProps
#
API: function mergeCellProps(base: CellProps, extra: CellProps): CellProps
合并两个 cellProps(单元格属性)对象,返回一个合并后的全新对象
mergeCellProps 会按照以下规则来合并两个对象:
- 对于 数字、字符串、布尔值类型的字段,extra 中的字段值将直接覆盖 base 中的字段值(className 是个特例,会进行字符串拼接)
- 注意在 v1.2 之前 className 会被覆盖
- 对于函数/方法类型的字段(对应单元格的事件回调函数),mergeCellProps 将生成一个新的函数,新函数将按序调用 base 和 extra 中的方法
- 对于普通对象类型的字段(对应单元格的样式),mergeCellProps 将合并两个对象
proto
#
详见 proto
smartCompare
#
API: (x: any, y: any) => number
比较字符串、数字、null 或是数组,返回一个负数表示「x 小于 y」,返回 0 表示「x 等于 y」,返回一个正数表示「x 大于 y」。
- 对于字符串将比较两者的字典序;
- 对数字将比较两者大小;
- null 值在比较时总是小于另一个值;
- 对于数组来说,将逐个比较数组中的元素,第一个不相等的比较结果将作为整个数组的比较结果
- 数组的比较可参考 python 中的元祖比较:https://stackoverflow.com/questions/5292303/how-does-tuple-comparison-work-in-python
traverseColumn
#
deprecated
该 API 已经过时,请使用 makeRecursiveMapper
API: (fn: (column, ctx) => NormalizeAsArrayInput<ArtColumn>) => TableTransform
traverseColumn
方法可用来简化「创建针对列的 transform」。提供一个针对单个 column 配置的转换函数,该方法可以生成对应的 TableTransform。fn 的表现如下:
- fn 被调用时的参数:
- column 参数:表格的列配置
- ctx:与 column 对应的上下文对象:
- ctx.range:列的下标,包含 ctx.range.start, ctx.range.end 两个下标
- ctx.dataSource:表格的数据源
- fn 的返回结果:
- 返回
null
时,对应的列将被移除; - 返回
ArtColumn
或一个数组时,返回的结果会替换对应的列。
- 返回
makeRecursiveMapper
#
根据 fn
生成一个递归的映射函数,该函数可以递归地处理树形数据。
API: <T extends AbstractTreeNode>( fn: (node: T, info: RecursiveFlatMapInfo<T>) => null | T | T[] ) => (rows: T[]) => T[]
其中 RecursiveFlatMapInfo 如下
type RecursiveFlatMapInfo<T> = { startIndex: number endIndex: number path: T[] isLeaf: boolean}
示例:
const tree1 = [ { value: 1, children: [{ value: 2 }, { value: 22 }] }, { value: 11, children: [{ value: 22, children: [{ value: 33 }, { value: 333 }] }] },]
// 将节点中的 value 变为原来的 2 倍const mapper = makeRecursiveMapper((node) => ({ ...node, value: node.value * 2 }))
// 调用 mapper(tree1) 可以得到以下结果:const result = [ { value: 2, children: [{ value: 4 }, { value: 44 }] }, { value: 22, children: [{ value: 44, children: [{ value: 66 }, { value: 666 }] }] },]