mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-10-29 08:58:22 +08:00
feat(table): laytpl 模板钩子支持
This commit is contained in:
@@ -181,7 +181,7 @@
|
||||
|
||||
// (b) 模板引擎优先级解析:tplFunction > tplLay > tplVue > tplLayId > tplVueId,
|
||||
// 提供一种即生效;五种全无且非 table 条目 → console.warn 并回退 table。
|
||||
// lay/vue/layId/vueId 的引擎挂载在任务 16(laytpl)/17(Vue),此处只做分发判定。
|
||||
// lay/layId 引擎挂载于 renderLayoutForm(任务 16,layui.laytpl);vue/vueId 挂载于任务 17。
|
||||
var resolveLayoutEngine = function (entry) {
|
||||
if (entry.name === 'table') {
|
||||
return {kind: 'table', entry: entry};
|
||||
@@ -231,6 +231,22 @@
|
||||
return resolveLayoutEngine(entry);
|
||||
};
|
||||
|
||||
// 模板管线失败回退(tplLayId 节点缺失 / laytpl 渲染错误 / Vue 引擎未挂载):
|
||||
// 当前形态归位 'table'(与"无钩子条目回退"同语义,幂等、不写 localStorage
|
||||
// 记忆,用户重新切换可再次触发),容器清空隐藏。调用方据 false 返回值做
|
||||
// 引擎纯渲染,随后的 syncLayoutVisibility 按 table kind 复显引擎数据区,
|
||||
// 避免"容器残留上一形态旧内容 + 引擎数据被隐藏"的视觉错位。
|
||||
var fallbackLayoutToTable = function (tableId, $container) {
|
||||
var layout = controlledLayouts[tableId];
|
||||
if (layout) {
|
||||
layout.current = 'table';
|
||||
}
|
||||
if ($container && $container.length) {
|
||||
$container.addClass('layui-hide').empty();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// 形态可见性同步:引擎数据区(表头+表体+合计行)与模板容器互斥显隐,
|
||||
// 引擎视图的工具栏(刷新/新增/批量删除等)两形态共用保持可见,搜索区
|
||||
// 本就挂在表格元素之前不受影响。非 table 形态下引擎根本不渲染行数据
|
||||
@@ -261,10 +277,10 @@
|
||||
// 模板形态的加载态容器标记(容器内加载样式由任务 14 的内置形态接入)
|
||||
var $layoutContainer = $('#ua-layout-' + tableId);
|
||||
$layoutContainer.addClass('ua-layout-loading');
|
||||
opts.done = function (res) {
|
||||
opts.done = function (res) {
|
||||
// 受控渲染分发:table 形态走引擎纯渲染(现状),非 table 形态走
|
||||
// 模板管线(渲染上下文 + 行级循环);模板管线不可用(引擎未挂载,
|
||||
// 任务 16/17 接管)时回退引擎纯渲染兜底
|
||||
// Vue 待任务 17;tplLayId 节点缺失/laytpl 渲染错误)时回退引擎纯渲染兜底
|
||||
var engineRender = function () {
|
||||
originalTableReloadData.call(table, tableId, {
|
||||
data: res.data,
|
||||
@@ -382,19 +398,32 @@
|
||||
// 空态容器;加载态由 store.fetch 的全局 loading 与容器的 ua-layout-loading
|
||||
// 标记承接(内置形态的加载态样式在任务 14 接入)。
|
||||
//
|
||||
// 【tplFunction 调用约定(任务 16/17 对接契约)】
|
||||
// 【tplFunction 调用约定】
|
||||
// 单行 HTML = tplFunction.call(rowCtx, rowCtx, listCtx)
|
||||
// - this/第一参 = 行上下文 {...row, _cells, _operatHtml, _checked, _disabled}
|
||||
// - 第二参 = 列表上下文 {tableId, rows, page, count, checkedAll}
|
||||
// - 返回值 = 该行的 HTML 字符串(框架直接拼接,不做转义)
|
||||
// 【laytpl 调用约定(tplLay / tplLayId)】
|
||||
// 单行 HTML = laytpl(tplLay | $(tplLayId).html()).render(rowCtx)
|
||||
// - d = 行上下文,与 tplFunction 第一参同构,另挂 d._list = 列表上下文
|
||||
// (与 tplFunction 第二参对齐;laytpl 仅支持单数据对象)
|
||||
// - 模板语法(layui 内置 laytpl v2.0.0 实测):{{ d.x }} 与 {{= d.x }}
|
||||
// 均经 laytpl.escape 转义;{{- d.x }} 原样输出(_cells/_operatHtml 等
|
||||
// HTML 内容必须用此形态);{{# }} 为 JS 语句(if/each 等)
|
||||
// - tplLayId 是页面 <script type="text/html"> 节点选择器,节点必须位于
|
||||
// 渲染容器之外(下方硬约束 2);script 内容为原始文本,laytpl 的 {{ }}
|
||||
// 不会被浏览器解析,.html() 读取即可
|
||||
// - laytpl 编译/运行错误不抛异常,render() 返回 "Laytpl Error: ..." 字符串
|
||||
// (laytpl 内部已 console.error 细节),框架探测到后按条目名 console.error
|
||||
// 并返回 false,调用方回退引擎纯渲染
|
||||
// 【两条硬约束】
|
||||
// 1. 模板容器恒带 class="layui-form"(form 控件渲染与事件受 .layui-form
|
||||
// 祖先约束,缺失则模板里的 switch/checkbox 全部失效);
|
||||
// 2. laytpl/Vue 模板节点(<script type="text/html"> / text/x-template)必须
|
||||
// 位于渲染容器之外,防止被模板引擎编译时吞掉 {{ }} 插值(节点解析在
|
||||
// 任务 16/17,节点由页面模板区提供)。
|
||||
// 返回 false 表示管线不可渲染(table 形态或模板引擎未挂载),调用方回退
|
||||
// 引擎纯渲染。
|
||||
// 位于渲染容器之外,防止被模板引擎编译时吞掉 {{ }} 插值(节点由页面
|
||||
// 模板区提供)。
|
||||
// 返回 false 表示管线不可渲染(table 形态或模板引擎未挂载/渲染失败),调用
|
||||
// 方回退引擎纯渲染。
|
||||
renderLayoutForm: function (tableId) {
|
||||
if (controlledLayouts[tableId] === undefined) {
|
||||
return false;
|
||||
@@ -409,10 +438,26 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
if (resolved.kind !== 'function') {
|
||||
// lay/vue/layId/vueId 分发点:引擎挂载于任务 16(laytpl)/17(Vue)
|
||||
console.warn('[ua.table] 模板引擎未挂载:' + resolved.kind + '(任务 16/17 实现),本次回退 table 形态');
|
||||
return false;
|
||||
// laytpl 引擎(任务 16):tplLay = 模板字符串;tplLayId = 模板节点选择器
|
||||
var laytplCompiled = null;
|
||||
if (resolved.kind === 'lay' || resolved.kind === 'layId') {
|
||||
var template;
|
||||
if (resolved.kind === 'layId') {
|
||||
var $tplNode = $(resolved.entry.tplLayId);
|
||||
if ($tplNode.length === 0) {
|
||||
console.error('[ua.table] tplLayId 节点不存在:' + resolved.entry.tplLayId
|
||||
+ '(形态 "' + resolved.entry.name + '"),本次回退 table 形态');
|
||||
return fallbackLayoutToTable(tableId, $container);
|
||||
}
|
||||
template = $tplNode.html();
|
||||
} else {
|
||||
template = resolved.entry.tplLay;
|
||||
}
|
||||
laytplCompiled = laytpl(template);
|
||||
} else if (resolved.kind !== 'function') {
|
||||
// vue/vueId 分发点:引擎挂载于任务 17(Vue)
|
||||
console.warn('[ua.table] 模板引擎未挂载:' + resolved.kind + '(任务 17 实现),本次回退 table 形态');
|
||||
return fallbackLayoutToTable(tableId, $container);
|
||||
}
|
||||
|
||||
var context = ua.table.buildLayoutContext(tableId);
|
||||
@@ -420,9 +465,26 @@
|
||||
if (context.rows.length === 0) {
|
||||
html = '<div class="ua-layout-empty">无数据</div>';
|
||||
} else {
|
||||
$.each(context.rows, function (i, rowCtx) {
|
||||
html += resolved.entry.tplFunction.call(rowCtx, rowCtx, context);
|
||||
});
|
||||
try {
|
||||
$.each(context.rows, function (i, rowCtx) {
|
||||
if (laytplCompiled) {
|
||||
rowCtx._list = context;
|
||||
var rowHtml = laytplCompiled.render(rowCtx) || '';
|
||||
if (rowHtml.indexOf('Laytpl Error:') === 0) {
|
||||
// laytpl 错误不抛异常(实测),探测返回值后主动抛出,
|
||||
// 由外层 catch 统一告警并整体回退
|
||||
throw new Error(rowHtml);
|
||||
}
|
||||
html += rowHtml;
|
||||
} else {
|
||||
html += resolved.entry.tplFunction.call(rowCtx, rowCtx, context);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('[ua.table] 模板渲染失败(形态 "' + resolved.entry.name + '"):'
|
||||
+ e.message + ',本次回退 table 形态');
|
||||
return fallbackLayoutToTable(tableId, $container);
|
||||
}
|
||||
}
|
||||
|
||||
// 内置 card 形态容器挂网格布局类(样式见 public.scss 的 .ua-layout-cards),
|
||||
@@ -439,8 +501,9 @@
|
||||
return controlledLayouts[tableId] ? controlledLayouts[tableId].current : 'table';
|
||||
},
|
||||
// 切换当前形态:仅改写运行期状态并重渲染,不发起网络请求(数据取自
|
||||
// store 当页状态)。目标条目不存在返回 false;模板管线不可用(无钩子条目
|
||||
// 回退 table)时走引擎纯渲染兜底。
|
||||
// store 当页状态)。目标条目不存在返回 false;模板管线不可用(无钩子
|
||||
// 条目 / tplLayId 节点缺失 / laytpl 渲染错误,均已在 renderLayoutForm
|
||||
// 内归位 current='table')时走引擎纯渲染兜底。
|
||||
setLayoutForm: function (tableId, name) {
|
||||
var layout = controlledLayouts[tableId];
|
||||
if (!layout || !layout.byName[name]) {
|
||||
|
||||
Reference in New Issue
Block a user