Skip to main content

通用工具函数

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>[]

根据 idPropparentIdProp平铺的对象数组中构建对应的

  • 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 来获取表格中每个单元格的内容
  • 列隐藏:
    • 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[]

对树状结构的数据进行排序。

layeredSortArray#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」。

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 }] }] },]