我们在上一章完成了独立的查询模块。但有时候用户不想在软件功能模块之间跳来跳去,在管理数据的时候,他们可能会希望有一个简单快速的查询功能,在本章我们完成与数据列表绑定的各种查询功能。

本章不再说明需要import的内容,请在Visutal Studio Code中根据软件提示使用自动处理功能。

10.1 轻量查询

轻量查询是位于数据列表头部的下拉式的单个数据的项目的查询。

10.1.1 数据列定义

下面我们在主数据的column姓名身份证手机号操作这项季以外的列加上属性search: false,把身份证号数据列修改成如下的定义:

  1. {
  2. title: '身份证号',
  3. dataIndex: 'identityNumber',
  4. copyable: true,
  5. sorter: {
  6. multiple: 2,
  7. },
  8. renderText: (val: string) =>
  9. `${val.substr(0,3)}***${val.substr(val.length-3,3)}`,
  10. + //给AntD Form组件的透传定义,用来校验内容和规范输入内容
  11. + formItemProps: {
  12. + rules: [...fieldRuls['identity']],
  13. + normalize: fidleNormalizes['identity'],
  14. + },
  15. + //给目标HTML元件的属性定义,关闭自动完成功能
  16. + fieldProps: {
  17. + autoComplete: 'off',
  18. + },
  19. },

下面是手机号数据列的定义,我们没有设置校验规则,原因是实际的实际的业务场景中,用户查询身份证号的时候经一般都是需要精准匹配,但俺手机号查询的时候有可能根据一部分数字进行模糊匹配。

  1. {
  2. title: '手机号码',
  3. dataIndex: 'mobile',
  4. renderText: (val: string) =>
  5. `${val.substr(0,3)}***${val.substr(val.length-4,4)}`,
  6. + formItemProps: {
  7. + normalize: fidleNormalizes['identity'],
  8. + },
  9. + fieldProps: {
  10. + autoComplete: 'off',
  11. + },
  12. },

10.1.2 数据表定义

在数据表ProTable上,我们只需要增加一个属性

  1. search={{
  2. filterType: 'light',
  3. }}

现在可以看到下图的样子

image.png
单击向下箭头,可以展开只包含一个数据框的查询表
image.png
下面式身份证号校验的结果
10. 依附列表的快速查询 - 图3

10.1.3 Mock用按条件查询

前端输入的查询条件都会放到网络请求的param中传递到后端,在Mock中可以用如下的方式获取全部的查询条件

  1. const { current = 1, pageSize = 10, sort='', filter='', ...query} = req.query;

query将会是一个对象,每一条的键名(key)为前端传过来的字段(或参数)名,键值(value)为用字符错形式的查询条件。

上一章的Mock函数能够继续为本章内容提供服务。

10.2 表单查询

10.2.1 定义表单查询类型

只需要把ProTable的search改成如下内容就可以得到一个在数据表上方的form

  1. search={{
  2. filterType: 'query',
  3. defaultCollapsed: false,
  4. }}

10.2.2 显式启用校验规则

随便输入一些数字作为身份证号点击查询,可以看到合法性校验规则没有起作用
10. 依附列表的快速查询 - 图4
给ProTable增加一个form.ignoreRules属性,定义为false

  1. <ProTable<TYPE.Member, TYPE.PageParams>
  2. + form={{ ignoreRules: false}}

再试一下,我们会发现校验规则不仅起作用了,而且和创建、修改对话框中一样,每次输入都回激发校验动作(在轻量模式中只有点击确定才执行校验)
10. 依附列表的快速查询 - 图5

10.2.3 用复选框服务代码较少的字段

删除性别数据列的search属性,可以在查询表单中看到多了一个下拉列表
10. 依附列表的快速查询 - 图6
和创建、编辑的时候不同,用户查询的时候,往往需要选择某个字段的一个或多个代码值组合做查询条件。也就是我们要把单选的逻辑变成复选。对于性别这样选项较少的,可以用普通的复选框(Checkbox)来实现

在性别的数据列定义中,增加一个用于自定义渲染组件的属性

  1. {
  2. title: '性别',
  3. dataIndex: 'gender',
  4. hideInForm: true,
  5. valueEnum: genderEnum,
  6. filters: true,
  7. onFilter: (value, record) => record.gender == value,
  8. + renderFormItem: (item, { type, defaultRender, ...rest }, form) => {
  9. + if (type === 'form') {
  10. + return null;
  11. + }
  12. +
  13. + return (
  14. + <Checkbox.Group
  15. + options={getOptionsFormValueEnum(genderEnum).filter( (item: any) => item.value > 0)}
  16. + />
  17. + )
  18. + },
  19. },

现在可以看到下拉列表变成了复选框组,并且去掉了不需要的空代码
10. 依附列表的快速查询 - 图7

10.2.4 用复选下拉框服务代码稍多的字段

对于类似学历、政治面貌这种代码稍多的字段,用复选框会让软件界面变得比较拥挤或杂乱,此时比较适合用可以复选的下拉框。下面是完整的数据列定义:

  1. {
  2. title: '学历',
  3. dataIndex: 'education',
  4. - search: false,
  5. hideInTable: true,
  6. valueEnum: educationEnum,
  7. + renderFormItem: (item, { type, defaultRender, ...rest }, form) => {
  8. + if (type === 'form') {
  9. + return null;
  10. + }
  11. +
  12. + return (
  13. + <Select
  14. + mode="multiple"
  15. + placeholder="选择一个或多个"
  16. + allowClear={true}
  17. + style={{ width: '100%' }}
  18. + options={getOptionsFormValueEnum(educationEnum)}
  19. + />
  20. + )
  21. + },
  22. },

下面是好看的复选下拉框
10. 依附列表的快速查询 - 图8

10.2.5 如何处理代码较多的字段

类似民族这样代码较多的字段,当前尚未较为理想的展现手段,我们已经向Ant Design官方提出了组件功能升级建议并且被接受,现在值得期待管方升级。

在官方升级之前,我们目前只好使用复选下拉框来处理。

10.2.6 查询日期型字段的方法

在查询日期型字段的时候,实际业务往往需要针把日期范围作为查询条件,所以需要特别的处理。

下面我们给columns增加一个只在查询表单中的数据列来定义日期范围组件,并且用searchtransform方法形成两个特别的变量传递到后端:

  1. {
  2. title: '出生日期',
  3. dataIndex: 'birthday',
  4. valueType: 'dateRange',
  5. //不在数据表出现
  6. hideInTable: true,
  7. search: {
  8. //把组件值转换成更合适的形式
  9. transform: (value) => {
  10. return {
  11. startDate: value[0]? moment(value[0]).format('YYYY-MM-DD') : '',
  12. endDate: value[1]? moment(value[1]).format('YYYY-MM-DD') : '',
  13. };
  14. },
  15. },
  16. },

完成上面的定义就可以在查询表单中看到多了一个日期范围组件。

如果仔细想一下,现在的逻辑是不完整的,因为此时日期范围的两个值都是必须选择。但实际业务可能只选择一个(即在某日之后或之前),为满足这个要求,我们还需要增加一个allowEmpty属性,通过fieldProps传递:

  1. valueType: 'dateRange',
  2. + fieldProps: {
  3. + allowEmpty: [true,true],
  4. + },

下面是符合要求的日期范围组件
10. 依附列表的快速查询 - 图9
在控制台可以看到传递到后端的内容
10. 依附列表的快速查询 - 图10
查询逻辑已经完整的工作了,但这个新增加的数据列定义干扰了数据展示页面的内容——在下图可以看到多了一个日期范围的内容
10. 依附列表的快速查询 - 图11
目前Ant Design中没有现成的手段来解决这个问题,为此我们需要自己处理一下。

先在index.tsx的顶层定义一个ProColumnsEx类型,把ProColumns的定义扩展一下,增加一个hideInDescription属性(默认值为false

  1. export declare type ProColumnsEx<T = any> = ProColumns<T> & {
  2. hideInDescription?: boolean
  3. }

把数据列定义的修改成这个扩展类型

  1. - const columns: ProColumns<TYPE.Member>[] = [
  2. + const columns: ProColumnsEx<TYPE.Member>[] = [

最后给日期范围列加上hideInDescription属性

  1. valueType: 'dateRange',
  2. fieldProps: {
  3. allowEmpty: [true,true],
  4. },
  5. hideInTable: true,
  6. + hideInDescription: true,

ProDescriptions的属性做如下修改

  1. - columns={columns as ProDescriptionsItemProps<TYPE.Member>[]}
  2. + columns={columns.filter((column) => !column.hideInDescription)}

现在数据展示页就看不到这项内容了。

10.2.7 默认不做数据查询

进入数据列表就执行一次默认条件的查询,这并不是一个很好的设计。既产生了很多的查询操作,其逻辑展现也往往不是用户(尤其那些管理范围比较大的用户)所需要的(他更多的可能是想看一下汇总的分析情况而不是数据列表),所以我们用上一章使用过的ProTable的manualRequest属性来声明不再自动执行查询请求

  1. request={queryAllMember}
  2. + manualRequest

下面刚刚进入页面的样子,只有用户点击查询按钮才回显示数据列表
10. 依附列表的快速查询 - 图12

10.3 Mock查询函数

上一章的Mock函数能够继续为本章内容提供服务。

10.4 总结

在完成本章内容的过程中我们陆续发现了一些Ant Design组件的Bug和功能需求并与开源官方在Github上互动,这有助于推进开源程序的完善,反过来我们也能获得更好用的软件。

此外,除了仔细研读官方文档和范例代码以外,为了完成本章这样的内容,适当读一下组件的源代码非常有助于理解这些程序的工作逻辑,尤其在官方文档更新不及时的情况下,很多软件特性需要通过阅读软件代码和软件更新记录来深入了解。

目前我们在等待官方升级Select组件,优化选项较多时的展现方式。

版权说明:本文由北京朗思云网科技股份有限公司原创,向互联网开放全部内容但保留所有权力。