问题背景 & 影响
当前 ObjectUI 在列表页和记录详情页存在如下重大字段类型显示缺陷:
- lookup、master_detail 等关联字段在列表和详情页始终显示原始 ID(如
o1、p1),而非展开后的名称。
- 即便服务端已实现
$expand,客户端 fetch 时机和字段类型推断逻辑存在竞争和脱节。
- 不同 view(ObjectGrid / ListView / DetailView / DetailSection)对字段类型和 objectSchema enrichment 支持不一致,部分代码直接 fallback 至原始值/ID。
用户反馈截图
列表页 — Order/Product 字段显示 o1、p1 等原始 ID:
详情页 — ORDER 显示 o1,PRODUCT 显示 p1:

具体问题归纳(3个独立根因)
Bug 1: ListView $expand 竞争条件
位置: packages/plugin-list/src/ListView.tsx
// ListView.tsx L509-513
const expandFields = React.useMemo(
() => buildExpandFields(objectDef?.fields, schema.fields),
[objectDef?.fields, schema.fields],
);
expandFields 依赖异步加载的 objectDef,首次 fetch 时 objectDef 可能仍为 null,导致 expandFields = []
- 数据请求不带
$expand,服务端返回的 lookup 字段为原始 ID 字符串
- 即使后续 objectSchema 加载完成,数据本身已经是
"o1" 而非展开对象,LookupCellRenderer 没有 options 可以 resolve label
Bug 2: DetailView 不传 $expand,也不加载 objectSchema
位置: packages/plugin-detail/src/DetailView.tsx
// DetailView.tsx L86-92
if (dataSource && schema.objectName && schema.resourceId) {
dataSource.findOne(objectName, resourceId).then((result) => {
setData(result);
});
}
findOne() 调用完全不传 $expand 参数
- DetailView 不加载 objectSchema(不像 ObjectGrid 那样调用
getObjectSchema)
- 因此不知道哪些字段是 lookup/master_detail 类型,无法计算需要 expand 的字段
- 传给 DetailSection 的 fields 缺少 type 属性
Bug 3: DetailSection 缺少 objectSchema enrichment
位置: packages/plugin-detail/src/DetailSection.tsx
// DetailSection.tsx L76-86
const displayValue = (() => {
if (value === null || value === undefined) return '-';
if (field.type) { // ← 没有 type 就跳过 CellRenderer
const CellRenderer = getCellRenderer(field.type);
if (CellRenderer) {
return <CellRenderer value={value} field={field} />;
}
}
return String(value); // ← 直接 String()
})();
- 当
field.type 未指定时直接 String(value)
- 即使数据被 expand 成对象也可能显示
[object Object]
- select、percent 等类型也无法走到正确的 CellRenderer
根因总结
| # |
组件 |
问题 |
影响 |
| 1 |
ListView |
$expand 依赖异步 objectDef,首次 fetch 时 objectDef=null → 不带 $expand → 数据是原始 ID |
列表 lookup 字段始终显示 ID |
| 2 |
DetailView |
findOne() 不传 $expand,不加载 objectSchema |
详情页 lookup 字段显示原始 ID |
| 3 |
DetailSection |
field.type 未指定时直接 String(value) → 无法利用类型感知的 CellRenderer |
所有无 type 的字段渲染失败 |
修复建议
- ListView:确保
objectDef 加载完成后再发起数据 fetch(或在 objectDef 变化后 re-fetch 带上 $expand)
- DetailView:参照 ObjectGrid,先加载
objectSchema → buildExpandFields → findOne(resourceId, { $expand }),并将 objectSchema 传给 DetailSection
- DetailSection:当
field.type 为空时,从 objectSchema 中查找字段类型、options 等元数据,参考 ObjectGrid generateColumns 的 enrichment 逻辑
涉及文件
packages/plugin-list/src/ListView.tsx
packages/plugin-grid/src/ObjectGrid.tsx
packages/plugin-detail/src/DetailView.tsx
packages/plugin-detail/src/DetailSection.tsx
验收标准
关联
问题背景 & 影响
当前 ObjectUI 在列表页和记录详情页存在如下重大字段类型显示缺陷:
o1、p1),而非展开后的名称。$expand,客户端 fetch 时机和字段类型推断逻辑存在竞争和脱节。用户反馈截图
列表页 — Order/Product 字段显示
o1、p1等原始 ID:详情页 — ORDER 显示
o1,PRODUCT 显示p1:具体问题归纳(3个独立根因)
Bug 1: ListView
$expand竞争条件位置:
packages/plugin-list/src/ListView.tsxexpandFields依赖异步加载的objectDef,首次 fetch 时objectDef可能仍为null,导致expandFields = []$expand,服务端返回的 lookup 字段为原始 ID 字符串"o1"而非展开对象,LookupCellRenderer 没有 options 可以 resolve labelBug 2: DetailView 不传
$expand,也不加载 objectSchema位置:
packages/plugin-detail/src/DetailView.tsxfindOne()调用完全不传$expand参数getObjectSchema)Bug 3: DetailSection 缺少 objectSchema enrichment
位置:
packages/plugin-detail/src/DetailSection.tsxfield.type未指定时直接String(value)[object Object]根因总结
ListView$expand依赖异步objectDef,首次 fetch 时objectDef=null→ 不带$expand→ 数据是原始 IDDetailViewfindOne()不传$expand,不加载objectSchemaDetailSectionfield.type未指定时直接String(value)→ 无法利用类型感知的 CellRenderer修复建议
objectDef加载完成后再发起数据 fetch(或在objectDef变化后 re-fetch 带上$expand)objectSchema→buildExpandFields→findOne(resourceId, { $expand }),并将 objectSchema 传给 DetailSectionfield.type为空时,从 objectSchema 中查找字段类型、options 等元数据,参考 ObjectGridgenerateColumns的 enrichment 逻辑涉及文件
packages/plugin-list/src/ListView.tsxpackages/plugin-grid/src/ObjectGrid.tsxpackages/plugin-detail/src/DetailView.tsxpackages/plugin-detail/src/DetailSection.tsx验收标准
-pnpm test全部通过关联