ant-design / pro-components

🏆 Use Ant Design like a Pro!
https://pro-components.antdigital.dev
MIT License
4.04k stars 1.29k forks source link

💥 feat(table): add form values to transform fields #426

Closed itsuki0927 closed 3 years ago

itsuki0927 commented 3 years ago

添加属性renameKey然后实现表单搜索的时候重命名字段.

  1. 重命名某一个字段并且valueType不是日期区间可以传入string | [string].
  2. 重命名valueType是日期区间传入[string, string].
  3. 不传入则不会进行重命名
const columns = [
  {
    title: '状态',
    dataIndex: 'state',
    renameKey: 'status',
  },
  {
    title: '标签',
    dataIndex: 'labels',
    renameKey: ['label'],
  },
  {
    title: '创建时间',
    key: 'since',
    dataIndex: 'created_at',
    valueType: 'dateRange',
    renameKey: ['startTime', 'endTime'],
  },
];

// 最终生成的`params`:
const params =  {
 status: '',
 label: '',
 startTime: '',
 endTime: ''
}

close https://github.com/ant-design/pro-components/issues/318

codecov[bot] commented 3 years ago

Codecov Report

Merging #426 into master will increase coverage by 0.05%. The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #426      +/-   ##
==========================================
+ Coverage   91.54%   91.60%   +0.05%     
==========================================
  Files         133      134       +1     
  Lines        3621     3643      +22     
  Branches     1303     1308       +5     
==========================================
+ Hits         3315     3337      +22     
  Misses        302      302              
  Partials        4        4              
Impacted Files Coverage Δ
packages/table/src/Table.tsx 96.13% <ø> (ø)
packages/table/src/Form/index.tsx 97.01% <100.00%> (+0.21%) :arrow_up:
...ackages/utils/src/transformKeySubmitValue/index.ts 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more Δ = absolute <relative> (impact), ø = not affected, ? = missing data Powered by Codecov. Last update 068409d...bd55558. Read the comment docs.

hengkx commented 3 years ago

你的意思是 表格中的列 和查询的 字段 不一致 对吗?

chenshuai2144 commented 3 years ago

这个名字有点,怎么说呢 很山寨的感觉

hengkx commented 3 years ago

searchKey😊

itsuki0927 commented 3 years ago

如果是ProTable需要这个属性的话,searchKey肯定是更好的,我的想法是不止ProTable可以使用这个属性, 可能到时候ProForm也可能会用到这个属性,比如说在ProForm表单中time:['日期1', '日期2'],需要转化为startTime: '日期1',endTime: '日期2'这样子的数据传递给后端.

在实现的过程中,我考虑过比如说state:[1,2,3]这种要不要进行兼容,后面发现因为数组具有不确定因素(renameKey与需要转换的value数组未必是等长的),所以后面我自己的想法是,最常见的就是将日期数组转换成time:['日期1', '日期2']转换为startTime: '日期1', endTime: '日期2',或者说将某一个key从这个a -> b这样子的, 像复杂的转换可以通过一个函数来实现(想着后面进行实现), 或者说通过beforeSubmitValue 回调来实现.

这是我的一些想法,,有更好的方案和思路,多多指教.

hengkx commented 3 years ago

cc @ant-design/ant-design-collaborators

chenshuai2144 commented 3 years ago
nameTransform: ['startDate', 'endDate'],

我们期望做成这样,可以让 range 系列的组件支持一下这个属性吗? 这样 table 和 form 都能支持

hengkx commented 3 years ago
nameTransform: ['startDate', 'endDate'],

我们期望做成这样,可以让 range 系列的组件支持一下这个属性吗? 这样 table 和 form 都能支持

这是 改antd里面多组件 增加特性吗?感觉可以 但是觉得 这个 名称 有点怪怪的 在真实使用场景中 大多数 都需要 自己 转换一次 @afc163

itsuki0927 commented 3 years ago
nameTransform: ['startDate', 'endDate'],

我们期望做成这样,可以让 range 系列的组件支持一下这个属性吗? 这样 table 和 form 都能支持

如果是这样子的话, 只能把这个props写到fieldProps里面配置了, 不能写在顶层. 本质上他们都一个操作就是format, 一个是format value 一个是format key, renameconversionSubmitValue操作写到一块

kerm1it commented 3 years ago

个人比较倾向于像 transformer 这一类的名称,这样其值的格式就比较宽泛,例如,可以用 Map 对象格式去做简单的转换,也可以传入函数做像日期范围那样复杂的转换。

afc163 commented 3 years ago

这种太难理解了,也不灵活,不如让 search 属性里增加一个 function,在这里做一些搜索表单请求需要的字段转化。

itsuki0927 commented 3 years ago

个人比较倾向于像 transformer 这一类的名称,这样其值的格式就比较宽泛,例如,可以用 Map 对象格式去做简单的转换,也可以传入函数做像日期范围那样复杂的转换。

我之前也是这样子想的, 在ProTable添加一个顶层属性transformer, 然后进行转换, 但是我想的是统一, 因为现在ProTableForm之间是都是依赖于 column这个props的.

shaodahong commented 3 years ago

https://github.com/ant-design/ant-design/issues/19727#issuecomment-574097570

之前这里讨论过类似的,其实不仅是字段的转化,还会涉及到值的转化

yutingzhao1991 commented 3 years ago

nameTransform: ['startDate', 'endDate'], +1,其实就是对 Filed 的 name 做了一个转换。

afc163 commented 3 years ago

建议用 function 而不是 array 来描述,另外 nameTransform 看不出来是转换到哪了,转换场景是什么。

这样如何?

search: {
  transform: (fields) => {
    return fields;
  },
  customRequest: (fields) => {
    // axio.get(fileds);
  },
},
itsuki0927 commented 3 years ago

建议用 function 而不是 array 来描述。

复杂情况下用function不是更好嘛, 简单的转化使用string | array即可.

chenshuai2144 commented 3 years ago

@afc163 这个其实是数组值的 name 映射,如果不能配置要 function 的话,可视化配置就没法完成了。

name-> 多个name 是个比较常见的场景,现在就是要通过 onFinish 这个方法来进行映射,如果是方法反而有点难用了

afc163 commented 3 years ago

映射 API 的可读性很差,不太能看出来干啥用的。

itsuki0927 commented 3 years ago

@afc163 根据两个数组[key], [value] 生成相对应{key: value}对象. 类似于lodash的zipObject.

映射的话两个元素的数组还算好理解, 如果是三个以上可读性确实是个问题, 所以我感觉这种的话, 在提供一个函数出来进行处理更加适合, 也就是说映射API就只有string, [string]、[string, string], 不提供多的映射API,其他要处理的都算是复杂映射,通过函数来处理.

zombieJ commented 3 years ago

要不加个 search,把 hideInSearch 收编到一起?

const columns = [
  {
    title: '标题',
    dataIndex: 'title',
    search: false,
  {
    title: '创建时间',
    dataIndex: 'created_at',
    valueType: 'dateRange',
    search: {
      queryParam: ['startTime', 'endTime'],
    },
  },
];
itsuki0927 commented 3 years ago

要不加个 search,把 hideInSearch 收编到一起?

const columns = [
  {
    title: '标题',
    dataIndex: 'title',
    search: false,
  {
    title: '创建时间',
    dataIndex: 'created_at',
    valueType: 'dateRange',
    search: {
      queryParam: ['startTime', 'endTime'],
    },
  },
];

这样子是可以的, 但是如果是ProForm创建也需要transformer呢?

afc163 commented 3 years ago

有函数就够用了,不再提供语法糖了。

itsuki0927 commented 3 years ago

如果是采用函数的话, 应该怎么设计呢, search: (fieldName, value, values) => newFieldName这种方式?

kerm1it commented 3 years ago

如果是采用函数的话, 应该怎么设计呢, search: (fieldName, value, values) => newFieldName这种方式?

应该是在顶级定义一个函数,把值传进去,然后返回新的值,方法中可以对字段和值进行任意转化,返回的值会直接用于搜索。

itsuki0927 commented 3 years ago

如果是采用函数的话, 应该怎么设计呢, search: (fieldName, value, values) => newFieldName这种方式?

应该是在顶级定义一个函数,把值传进去,然后返回新的值,方法中可以对字段和值进行任意转化,返回的值会直接用于搜索。

这样子的话,感觉会有一些重复操作, 比如说dateRange类型的数据, 每一个都得转成{startTime:'xxx', endTime: 'xxx'}, 虽然可以将函数拆分成最小单元, 然后利用组合的方式来进行复用, 但是现在已经有一个顶级API beforeSubmitValue就是这样子的一个功能.

beforeSearchSubmit : 搜索之前进行一些修改

afc163 commented 3 years ago

https://github.com/ant-design/pro-components/pull/426#issuecomment-689288532 如何

chenshuai2144 commented 3 years ago

@afc163 你这个 api 太复杂了,没有想写的冲动

afc163 commented 3 years ago

customRequest 暂时不需要实现。

afc163 commented 3 years ago

如果已经有 beforeSubmitValue 能实现相关功能,感觉不需要加 API 了。

itsuki0927 commented 3 years ago

@afc163 我没有理解你的意思... 已经有beforeSubmitValue这样子的API了

afc163 commented 3 years ago

或者:

const columns = [
  {
    title: '标题',
    dataIndex: 'title',
    search: false,
  {
    title: '创建时间',
    dataIndex: 'created_at',
    valueType: 'dateRange',
    search: {
      transform: fields => fields,
    },
  },
];
itsuki0927 commented 3 years ago

@afc163 这样子的话,不提供最基本的语法糖比如说string | array, 直接让用户自己去转换.

afc163 commented 3 years ago

我倾向是的,zipObject 这个 API 我就不太能看懂。

hengkx commented 3 years ago

好复杂 我已经 完全 懵逼了😩

kerm1it commented 3 years ago

@afc163, @itsuki0927 开这个PR的意思其实就是想提供一些快捷转换字段的语法糖,减少平时一些重复性的转换(日期范围字段拆分,字段重命名等),因为复杂的转换,已经有 beforeSubmitValue 了,所以现在其实就是讨论一下,我们要不要提供这些,如果不需要的话,感觉这个PR就完全没必要了。

afc163 commented 3 years ago

仔细看了一下 #318。

真实需求是在搜索前做一些必要的转换,将显示字段变成搜索字段,比如时间格式,搜索的时候不是一个时间,需要变成一个时间区间。

现在已经有 beforeSubmitValue 了,确实可以实现,但是存在两个问题:

  1. beforeSubmitValue 是 ProTable 顶层 API,是所有字段统一转换的代码,不方便针对某个字段写相应的转换,逻辑容易分散(字段定义写在 columns 里,转换逻辑需要写到 beforeSubmitValue 里)。
  2. 没有统一语法糖,写起来略繁琐,不能序列化。

问题一我觉得是要解的,即把同一个字段相关的逻辑都写到一起,方便逻辑收敛/重构/迁移。建议参考 @zombieJ 的 API,用 column.search 来统一描述列在搜索框里的状态和信息。

const columns = [
  {
    title: '标题',
    dataIndex: 'title',
    search: false, // 替代 hideInSearch
  {
    title: '创建时间',
    dataIndex: 'created_at',
    valueType: 'dateRange',
    search: {
      xxx: 'xxx',
      yyy: 'yyy',
    },
  },
];

问题二,需要找到一种好理解的语法糖才行,否则与其提供一个语义不清晰的语法糖,不如还是老老实实写 function。

目前的几个命名方案:

renameKey: ['startTime', 'endTime'],
queryParam: ['startTime', 'endTime'],
nameTransform: ['startTime', 'endTime'],

本质上定义了 search 请求参数的 key 列表。

  1. 格式上相对费解,日期范围数组的值对应每个 key 的 value。
  2. 不通用,如果需要做更复杂的转换无法支持,比如嵌套结构/更长的数组。
  3. valueType: 'dateRange' 强绑定,性价比较低。

我建议在找到一个好的语法糖之前,还是先提供通用的 transform 函数,一先解决代码分治问题,二是保持通用性。最终 API 如下:

const columns = [
  {
    title: '标题',
    dataIndex: 'title',
    search: false, // 替代 hideInSearch
  {
    title: '创建时间',
    dataIndex: 'created_at',
    valueType: 'dateRange',
    search: {
      transform: fields => {
        return {
          startTime: fields[0],
          endTime: fields[1],
        };
      },
    },
  },
];
itsuki0927 commented 3 years ago

@afc163 👍

hengkx commented 3 years ago

hideInSearch 标记废弃 后面 移除把

itsuki0927 commented 3 years ago

我个人开发的时候一般在功能分支代码使用rebase mater来获取上游的最新代码, 我上次也是这个问题, 出现了冲突,然后@chenshuai2144 说的是merge mater, 所以我现在有点纠结应该是使用哪个来获取上游代码?

chenshuai2144 commented 3 years ago

直接用merge pr合并的时候会处理

hengkx commented 3 years ago

check ci

hengkx commented 3 years ago

单元测试 多增加一点

hengkx commented 3 years ago

image

itsuki0927 commented 3 years ago

@hengkx 好的, 我晚点增加一些测试用例, 感谢🙏.

hengkx commented 3 years ago

标题也改一下吧

chenshuai2144 commented 3 years ago

@hengkx @afc163

  transform: fields => {
        return {
          startTime: fields[0],
          endTime: fields[1],
        };
      },

是不是可以支持一下简写,

  //  { [transform[0]: filedValue[0] }
  transform: ['startTime','endTime']
zombieJ commented 3 years ago

@hengkx @afc163

  transform: fields => {
        return {
          startTime: fields[0],
          endTime: fields[1],
        };
      },

是不是可以支持一下简写,

  //  { [transform[0]: filedValue[0] }
  transform: ['startTime','endTime']

先别了,否则又绕回来了。fields 作为入参会更清晰些

chenshuai2144 commented 3 years ago

加个 demo 吧,输出一下 onFinish 的内容

itsuki0927 commented 3 years ago

是文档中加一个demo,还是测试案例加一个demo?

chenshuai2144 commented 3 years ago

文档中加一个,用于展示能力,这个api 文档不一定能看懂