Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

列头排序在服务端分页下只排了当前页:data-table 的排序意图没有出口能到达发请求的那一层 #3106

Closed

Description

@os-zhuang

TL;DR

服务端分页的列表里点列头排序,排的只是当前这一页。用户看到的是「按这一列排好了」,拿到的是「这 50 行内部排好了,第 2 页从头再来」。排序生效了,只是作用域不是用户以为的那个集合。

这是 #3096 的同一条原则(看起来在排 A,实际在排 B)在作用域维度上的复现,与 framework#3948「未生效的表达式不该看起来生效了」同源。#3096 只收口了「排序键」,没有碰「排序范围」。

链路(每一环都读过代码,非推测)

data-table 的排序完全是组件内部 state,整个文件没有任何 onSortChange / onSortingChange / manualSorting 回调 —— 排序意图没有任何出口能到达发请求的那一层:

  • const [sortColumn, setSortColumn] = useState(...)(packages/components/src/renderers/complex/data-table.tsx:474)
  • sortedData 排的是 filteredData,也就是传进来的那批行(:612)
  • paginatedData = (pagination && !manualPagination) ? slice(...) : sortedData(:634)—— 服务端分页下直接渲染排好序的当前页

而当前页确实只有一页数据:

  • ListView 自己取一页,并把 manualPagination: true + rowCount: serverTotal 交给网格(packages/plugin-list/src/ListView.tsx:2676-2677)
  • ObjectGrid 转发 manualPagination / rowCount / page 给 DataTable(packages/plugin-grid/src/ObjectGrid.tsx:1925-1927)
  • ObjectGrid 自己取数时同样是 $top/$skip 一页(:521-525,useServerPagination 见 :1892)

影响所有列,不只关联列。

RelatedList 更隐蔽

它自己的排序按钮行 sortable 默认 false(packages/plugin-detail/src/RelatedList.tsx:235),而它内嵌的 data-table 没有传 sortable,取默认 true(viewSchema 只关掉了 pagination/searchable/exportable,见 :889 附近)。

于是默认配置下,窗口化关联列表里唯一的排序入口就是这个页内排序,没有任何提示。开了 sortable 之后更糟:按钮行是服务端全局排序,列头是页内客户端排序,同一张卡片里两套语义。

为什么现在提

#3096 的修复让这条更值得担心了:在那之前,点 lookup 列头得到的是垃圾顺序(比较器退化成常量),没人会当真;修完之后它在页内产生令人信服的字母序,用户会顺理成章读成「整个列表按负责人排好了」。可信度提上去了,作用域的谎还在。

选项

  1. 列头排序接上服务端 $orderby —— DataTable 增加 onSortChange,服务端分页时不再本地排;ObjectGrid/ListView 把它并进已有的视图 sort 通路。好处是列头和工具栏排序合流、语义统一,并且自动继承 lookup 列排序按裸外键 id 排:服务端 $orderby 发平面 FK 字段,单元格却显示 $expand 后的标签 #3096 的关联列收口(关联列头同样不该发服务端排序)。代价是要想清楚它与已保存视图 sort 的优先级,以及是否落盘。
  2. 显式标注作用域 —— 服务端分页时把列头排序标注/降级为「仅当前页」(或直接禁用,把用户导向工具栏排序)。最小改动,先消除误导。
  3. RelatedList 单独收口 —— 至少让内嵌 data-table 的 sortable 跟随 RelatedList 自己的 sortable,消掉「一张卡片两套排序语义」。

倾向 1(与 #3096 收口后的通路一致);若 1 的排期长,先上 2 + 3 止血。

关联

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions