列表行自定义渲染
概念说明
本文档是 视图列表 概念的具体配置说明。建议先阅读视图列表概念,了解整体架构。
视图列表列表行支持自定义渲染,可以根据行数据的具体内容使用自定义的HTML或JavaScript代码进行渲染展示。
功能概述
列表行自定义渲染支持两种模式:
| 模式 | 说明 | 适用场景 |
|---|---|---|
| HTML模式 | 直接编写HTML代码,支持占位符替换 | 简单的数据展示,固定的HTML结构 |
| JavaScript模式 | 编写JavaScript函数返回HTML字符串 | 复杂的逻辑判断,动态生成HTML |
配置步骤
1. 开启自定义渲染
在视图列表字段配置中,找到 自定义渲染配置 区域,开启 启用自定义渲染 开关。
2. 选择渲染模式
通过 渲染模式 切换按钮选择使用哪种模式:
- HTML模式:适用于简单的数据展示
- JavaScript模式:适用于需要复杂逻辑处理的场景
3. 编 辑渲染代码
点击 编辑代码 按钮,在弹出的代码编辑器中编写渲染代码。
HTML模式
占位符语法
在 HTML 模式下,可以使用 {data.Fields.xxx.Text} 占位符来插入行数据:
<div>
<span>名称:{data.Fields.name.Text}</span>
<span>状态:{data.Fields.status.Text}</span>
</div>
占位符说明:
{data.Fields.xxx}是列表行自定义渲染的占位符语法(注意:不带$符号)data表示当前行的 ObjectData 对象data.Fields.xxx.Text访问字段的文本值data.Fields.xxx.Value访问字段的实际值- 占位符格式:
{data.Fields.字段编码.Text}或{data.Fields.字段编码.Value}
注意
HTML 模式的占位符使用 {xxx} 格式,不 要与 JavaScript 模板字符串的 ${xxx} 语法混淆。
使用示例
示例1:简单的字段展示
<div style="padding: 8px;">
<span style="font-weight: bold;">{data.Fields.name.Text}</span>
<span style="margin-left: 8px; color: #666;">{data.Fields.status.Text}</span>
</div>
示例2:带样式的状态标签
<div>
<span style="font-weight: bold;">{data.Fields.name.Text}</span>
<span style="display: inline-block; padding: 2px 8px; background-color: #52c41a; color: white; border-radius: 4px; margin-left: 8px;">
{data.Fields.status.Text}
</span>
</div>
JavaScript模式
脚本结构
在 JavaScript 模式下,需要编写一个函数来返回 HTML 字符串:
function renderHtml(api, data) {
// 获取字段值
const name = data.Fields.name?.Text || '未命名';
const status = data.Fields.status?.Text || '未知';
// 返回HTML字符串 (使用 JavaScript 模板字符串语法 ${})
return `<div>
<span style="font-weight: bold;">${name}</span>
<span style="margin-left: 8px;">${status}</span>
</div>`;
}
重要说明
JavaScript 模式使用标准的 JavaScript 模板字符串语法 ${expression} 来插入变量,而不是 HTML 模式的 {prefix.xxx} 占位符。
参数说明
| 参数 | 类型 | 说明 |
|---|---|---|
| api | object | API 对象,提供系统内置辅助函数(如 isMobile()),详见 API 支持列表 |
| data | Models.ObjectData | 当前行数据对象 |
API 支持列表
在 JavaScript 模式下,api 对象提供以下内置函数:
| API | 类型 | 返回值 | 说明 | 使用示例 |
|---|---|---|---|---|
api.isMobile() | 函数 | boolean | 判断当前设备是否为移动端,移动端返回 true,否则返回 false | if (api.isMobile()) { ... } |
说明
API 支持列表会持续扩展,后续版本会加入更多系统内置辅助函数,例如:判断当前渲染环境、获取当前用户信息等。
使用示例:根据设备类型渲染不同内容
function renderHtml(api, data) {
const name = data.Fields.name?.Text || '未命名';
const status = data.Fields.status?.Text || '未知';
// 移动端显示简洁样式
if (api.isMobile()) {
return `<div style="padding: 8px; font-size: 12px;">
<span style="font-weight: bold;">${name}</span>
</div>`;
}
// 桌面端显示完整样式
return `<div style="padding: 8px;">
<span style="font-weight: bold;">${name}</span>
<span style="margin-left: 8px; color: #666;">${status}</span>
</div>`;
}
ObjectData 结构
传递给脚本的 data 参数是一个 ObjectData 对象,结构如下:
{
Id: "数据ID",
Fields: {
"字段编码1": {
Code: "字段编码1",
Text: "字段文本值",
Value: "字段实际值"
},
"字段编码2": {
Code: "字段编码2",
Text: "字段文本值",
Value: "字段实际值"
},
// 更多字段...
}
}
使用示例
示例1:基于条件动态渲染
function renderHtml(api, data) {
// 根据状态显示不同的标签样式
const status = data.Fields.status?.Text || '未知';
let statusStyle = '';
if (status === '激活') {
statusStyle = 'background-color: #52c41a; color: white;';
} else if (status === '未激活') {
statusStyle = 'background-color: #ff4d4f; color: white;';
} else {
statusStyle = 'background-color: #d9d9d9; color: #666;';
}
return `<div style="padding: 8px;">
<span style="font-weight: bold;">${data.Fields.name?.Text || '未命名'}</span>
<span style="display: inline-block; padding: 2px 8px; ${statusStyle} border-radius: 4px; margin-left: 8px;">
${status}
</span>
</div>`;
}
示例2:格式化金额显示
function renderHtml(api, data) {
// 格式化金额
const amount = parseFloat(data.Fields.amount?.Value || 0);
const formattedAmount = amount.toFixed(2);
const amountColor = amount > 1000 ? 'color: red;' : 'color: green;';
return `<div style="padding: 8px;">
<span>${data.Fields.name?.Text || '未命名'}</span>
<span style="${amountColor} font-weight: bold; margin-left: 8px;">
¥${formattedAmount}
</span>
</div>`;
}
示例3:显示多个字段组合
function renderHtml(api, data) {
const name = data.Fields.name?.Text || '未命名';
const createTime = data.Fields.createTime?.Text || '';
const creator = data.Fields.createdby?.Text || '';
return `<div style="padding: 8px; border-bottom: 1px solid #eee;">
<div style="font-weight: bold; margin-bottom: 4px;">${name}</div>
<div style="color: #666; font-size: 12px;">
<span>${creator}</span>
<span style="margin-left: 8px;">${createTime}</span>
</div>
</div>`;
}
示例4:条件性显示内容
function renderHtml(api, data) {
const status = data.Fields.status?.Text;
const isEditable = data.Fields.isEditable?.Value === 'true';
let editButton = '';
if (isEditable && status === '待审批') {
editButton = `<button style="margin-left: 8px; padding: 2px 8px; background-color: #1890ff; color: white; border: none; border-radius: 4px; cursor: pointer;">
编辑
</button>`;
}
return `<div style="padding: 8px;">
<span>${data.Fields.name?.Text || '未命名'}</span>
<span style="margin-left: 8px; color: #666;">${status}</span>
${editButton}
</div>`;
}
注意事项
1. 字段访问安全性
在访问字段时,建议使用可选链操作符 ?. 或添加默认值,避免字段不存在时出错:
// 推荐:使用可选链和默认值
const name = data.Fields.name?.Text || '未命名';
// 不推荐:直接访问可能不存在的字段
const name = data.Fields.name.Text; // 如果name字段不存在会报错
2. 样式必须内联
所有样式必须内联到 HTML 元素中,不支持使用 <style> 标签或外部样式表:
// 推荐:内联样式
return `<div style="color: red; font-weight: bold;">内容</div>`;
// 不支持:style标签
return `<style>.red { color: red; }</style><div class="red">内容</div>`;
3. 预览限制
JavaScript 模式在编辑器内不支持预览,需要保存后在列表页面中查看实际渲染效果。
4. 性能考虑
- 避免在函数中进行复杂的计算或网络请求
- 保持脚本逻辑简洁,快速返回结果
- 对于大量数据的列表,脚本性能会直接影响列表加载速度
5. 安全限制
- 不支持任何
<script>标签 - 不支持
onclick、on*等事件属性 - 不支持
javascript:协议
最佳实践
保持代码简洁
// 推荐:简洁明了
function renderHtml(api, data) {
const name = data.Fields.name?.Text || '未命名';
return `<div style="font-weight: bold;">${name}</div>`;
}
// 不推荐:复杂的逻辑
function renderHtml(api, data) {
// 避免在渲染函数中进行复杂的数据处理
const processedData = complexDataProcessing(data);
return `<div>${processedData}</div>`;
}
添加适当的默认值
function renderHtml(api, data) {
// 为可能为空的字段提供默认值
const name = data.Fields.name?.Text || '未命名';
const status = data.Fields.status?.Text || '未知';
const amount = parseFloat(data.Fields.amount?.Value || 0).toFixed(2);
return `<div>
<span>${name}</span>
<span style="margin-left: 8px;">${status}</span>
<span style="margin-left: 8px;">¥${amount}</span>
</div>`;
}
使用语义化的HTML结构
function renderHtml(api, data) {
return `<div style="padding: 12px;">
<div style="font-weight: bold; font-size: 14px;">${data.Fields.name?.Text}</div>
<div style="color: #666; font-size: 12px; margin-top: 4px;">
${data.Fields.description?.Text || '暂无描述'}
</div>
</div>`;
}
故障排除
字段值不显示
检查以下几点:
- 确认字段编码是否正确(区分大小写)
- 确认使用的是
.Text还是.Value - 检查字段是否存在于当前行的数据中
- 使用
console.log(data)查看完整的数据结构
样式不生效
检查以下几点:
- 确认样式是否内联到元素中
- 检查CSS属性名是否使用驼峰命名(如
backgroundColor而非background-color) - 确认样式值是否正确(如颜色值需要使用标准格式)
脚本执行错误
检查以下几点:
- 确认函数名正确(
renderHtml) - 检查JavaScript语法是否正确
- 确认所有使用的字段都存在或有默认值
- 查看浏览器控制台的错误信息
使用场景
- 自定义列表行样式
- 基于状态的条件渲染
- 数据格式化显示
- 多字段组合展示
- 特殊格式数据展示
- 行内操作按钮
相关文档
- 视图列表 - 视图列表概念介绍
- 行按钮动态显示控制 - 行按钮脚本API说明
- 自定义 HTML 组件 - HTML 组件详细说明