无需刷新页面更新Google Apps Script HTML模板中的Scriptlets
问题描述
我参考了Google Apps Script的HTML模板文档,现有代码能在页面加载时调用getData()从Google表格获取数据并渲染表格。现在想实现点击按钮调用getData()更新数据,无需刷新整个页面;目前尝试的代码虽能调用函数,但丢失了循环渲染逻辑,想知道是否可以重新评估页面或有其他解决方案。
现有代码
Code.gs
function doGet() { return HtmlService .createTemplateFromFile('Index') .evaluate(); } function getData() { return SpreadsheetApp .openById('1234567890abcdefghijklmnopqrstuvwxyz') .getActiveSheet() .getDataRange() .getValues(); }
初始HTML代码
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <? var data = getData(); ?> <table> <? for (var i = 0; i < data.length; i++) { ?> <tr> <? for (var j = 0; j < data[i].length; j++) { ?> <td><?= data[i][j] ?></td> <? } ?> </tr> <? } ?> </table> </body> </html>
尝试的更新代码
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <button type="button" onclick="Refresh()">Refresh</button> <? var data = getData(); ?> <table id="datatable"> <? for (var i = 0; i < data.length; i++) { ?> <tr> <? for (var j = 0; j < data[i].length; j++) { ?> <td><?= data[i][j] ?></td> <? } ?> </tr> <? } ?> </table> </body> <script> function Refresh(){ google.script.run.withSuccessHandler(update).withUserObject(this).getData(); } function update(returnValue){ document.getElementById("datatable").innerHTML= returnValue } </script> </html>
解决方案
你的核心问题是:getData()返回的是二维数组,直接赋值给表格innerHTML无法自动转换成HTML结构,导致渲染失效。以下两种方案可以解决:
方案一:前端处理数据生成表格
修改update函数,手动遍历返回的二维数组,构建表格HTML结构:
<script> function Refresh(){ google.script.run.withSuccessHandler(update).getData(); } function update(data){ let tableRows = ''; // 遍历每一行数据 for (let i = 0; i < data.length; i++) { tableRows += '<tr>'; // 遍历当前行的每一列 for (let j = 0; j < data[i].length; j++) { // 转义特殊字符避免XSS风险 const cellContent = data[i][j].toString().replace(/</g, '<').replace(/>/g, '>'); tableRows += `<td>${cellContent}</td>`; } tableRows += '</tr>'; } document.getElementById("datatable").innerHTML = tableRows; } </script>
方案二:后端生成HTML片段返回
修改getData()函数,直接返回拼接好的表格行HTML代码:
function getData() { const data = SpreadsheetApp .openById('1234567890abcdefghijklmnopqrstuvwxyz') .getActiveSheet() .getDataRange() .getValues(); let htmlRows = ''; for (let i = 0; i < data.length; i++) { htmlRows += '<tr>'; for (let j = 0; j < data[i].length; j++) { // 使用官方API转义特殊字符 htmlRows += `<td>${HtmlService.createHtmlOutput(data[i][j]).getContent()}</td>`; } htmlRows += '</tr>'; } return htmlRows; }
此时原update函数无需修改,直接赋值即可:
function update(returnValue){ document.getElementById("datatable").innerHTML = returnValue; }
关键提示
不要尝试重新评估整个页面,这会触发页面刷新,违背无更新的需求。两种方案都能实现局部刷新,可根据业务复杂度选择:前端处理更灵活,后端处理则减少前端代码量。
内容的提问来源于stack exchange,提问作者MOS
相关产品推荐
相关产品推荐

