在数据库中实现 js 与 Sprig 模板的交互
see https://ld246.com/article/1734002304855
在数据库模板中可以利用img标签实现 js 与 Sprig 模板的交互,利用 js 来处理数据,就更方便了。
比如:
.action{$blocks := queryBlocks "select * from blocks limit 1"}
<span><img src="" data-result='.action{toJson $blocks}' style="display:none;" onerror="
(async () => {
// 天气api
const weather = await fetch('https://wttr.in/?format=1');
const text = await weather.text();
// 解析数据
const result = JSON.parse(this.dataset.result);
const first = result[0];
const created = first.Created.replace(/^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/, '$1-$2-$3 $4:$5:$6');
// 输出数据
this.parentElement.outerHTML = `天气:${text}<br>ID:${first.ID}<br>创建时间:${created}`;
})();
" />Loading</span>
这里添加 style="display:none",防止加载时出现默认图片。
添加 span 标签包裹,为了在加载时显示 Loading 提示。
把数据模板查询到的数据存储到 img 标签的 data-result 属性里。
然后就可以方便的用 js 处理数据了,甚至可以请求 api 等。
效果:
其他示例:
see https://ld246.com/article/1734062837460
<span><img src="" style="display:none;" onerror="
(async () => {
// 获取当前单元格
const currCell = this.closest('div.av__cell');
// 获取当前行
const currRow = currCell.closest('div.av__row');
// 获取前一个单元格的值
let prevCellValue = 0;
let prevCellColId = '';
const prevCell = currCell.previousElementSibling;
if(prevCell && prevCell.matches('div.av__cell')) {
prevCellValue = parseFloat(prevCell.textContent);
prevCellColId = prevCell.dataset.colId;
}
// 获取前一个单元格的所有前面的单元格的和
let prevPrevCellsTotal = 0;
const prevPrevRows = getPrevSiblings(currRow);
prevPrevRows.forEach(prevPrevRow => {
if(prevPrevRow) {
const prevPrevCell = prevPrevRow.querySelector(`div.av__cell[data-col-id='${prevCellColId}']`);
if(prevPrevCell) {
prevPrevCellsTotal += parseFloat(prevPrevCell.textContent);
}
}
});
// 输出数据
this.parentElement.outerHTML = (prevCellValue + prevPrevCellsTotal).toFixed(2).replace('.00', '') || '';
// 获取所有前面的行
function getPrevSiblings(currRow) {
let siblings = [];
let sibling = currRow.previousElementSibling;
while (sibling) {
// 如果遇到了 div.av__row.av__row--header,则停止查找
if (sibling.tagName.toLowerCase() === 'div' && sibling.classList.contains('av__row--header')) {
break;
}
// 收集 div.av__row 元素
if (sibling.tagName.toLowerCase() === 'div' && sibling.classList.contains('av__row')) {
siblings.push(sibling);
}
sibling = sibling.previousElementSibling;
}
// 因为我们是从下往上添加的,所以最后需要反转数组来保持从上到下的顺序。
return siblings.reverse();
}
})();
" />正在计算...</span>
