在服务器-客户端往返期间存储(或传递)Element/TableCell 引用
Storing (or passing) an Element/TableCell reference during a server-client round-trip
我正在尝试使用 HTMLService 和 GAS 在 Google 文档中的给定 table 单元格上制作一个模式弹出窗口。
弹出窗口有效,通常我可以将数据从服务器脚本传递到客户端脚本并返回。我似乎无法传递的数据是打开弹出窗口时光标所在的table单元格。
方法 1:如果我将它直接传递给客户端并返回,引用将被破坏,因为它到达客户端时已经 null
了。我可以在完全相同的上下文中很好地传递单元格的内容,所以字符串可以工作,这只是它是一个单元格引用的事实。 (很有道理。)
方法 2:如果我将 TableCell 引用存储在服务器端的全局变量中,我会得到 Cannot call method "getText" of undefined
--第一次往返后引用未定义。 (我想服务器脚本会在那个时候完全重新加载。)
方法 3:如果我在客户端使用 CacheService.getUserCache(),当我尝试获取缓存的 TableCell 对象时,它似乎与我设置的对象断开连接,因为我得到了迄今为止未 Google可能的错误Cannot find function getText in object TableCell.
// server, before popup is opened:
cache.put('cell_currently_being_edited', active_doc.getCursor().getElement().getParent());
// popup client calls server function like so:
google.script.run.withSuccessHandler(load_content).get_starting_content();
// server, where the above error occurs:
function get_starting_content() {
var cell_currently_being_edited = cache.get('cell_currently_being_edited');
return cell_currently_being_edited.getText();
}
如果单元格具有某种我可以传递的固定 ID 值,那可能会起作用...
我会根据单元格中的文本来做,但我希望这不是唯一的选择,因为一般的单元格文本(是的,在这个特定的上下文中也是如此)可能不是唯一的,所以在一轮之后trip 当用户激活弹出窗口时,我可能最终会替换光标所在单元格中的文本。
解决方案:
- 您可以使用单元格索引作为唯一标识符在客户端和服务器之间来回传递 RC 字符串,因为字符串值是合法的。
- 使用 Properties/Cache 服务将 RC 索引信息存储为字符串,以便将来在服务器中检索(如果需要)。
示例脚本:
function getRCTIndexOfTable(tableCell) {
var tableRow = tableCell.getParentRow();
var table = tableRow.getParentTable();
var column = tableRow.getChildIndex(tableCell);
var row = table.getChildIndex(tableRow);
var body = table.getParent().asBody();
var tableId = body.getChildIndex(table);
return 'R' + row + 'C' + column + 'T' + tableId;
}
function main() {
var active_doc = DocumentApp.getActiveDocument();
var activeTableCell = active_doc
.getCursor()
.getElement()
.getParent()
.asTableCell();
Logger.log(getRCTIndexOfTable(activeTableCell));
}
参考文献:
由于另一个答案(即使在修改代码之后)集中在问题的 "saving" 一半,我想我会分享代码,其中包括如何在之后加载引用以完成往返:
// save
var table_cell = active_doc.getCursor().getElement().getParent();
var table_row = table_cell.getParentRow();
var table = table_row.getParentTable();
var column_index = table_row.getChildIndex(table_cell);
var table_index = active_doc.getBody().getChildIndex(table);
var row_index = table.getChildIndex(table_row);
cache.put('table_currently_being_edited', table_index);
cache.put('row_currently_being_edited', row_index);
cache.put('column_currently_being_edited', column_index);
// load
function get_cell_currently_being_edited() {
var table_index = cache.get('table_currently_being_edited');
var row_index = cache.get('row_currently_being_edited');
var column_index = cache.get('column_currently_being_edited');
return active_doc.getBody().getChild(table_index).getCell(row_index, column_index);
}
我正在尝试使用 HTMLService 和 GAS 在 Google 文档中的给定 table 单元格上制作一个模式弹出窗口。
弹出窗口有效,通常我可以将数据从服务器脚本传递到客户端脚本并返回。我似乎无法传递的数据是打开弹出窗口时光标所在的table单元格。
方法 1:如果我将它直接传递给客户端并返回,引用将被破坏,因为它到达客户端时已经 null
了。我可以在完全相同的上下文中很好地传递单元格的内容,所以字符串可以工作,这只是它是一个单元格引用的事实。 (很有道理。)
方法 2:如果我将 TableCell 引用存储在服务器端的全局变量中,我会得到 Cannot call method "getText" of undefined
--第一次往返后引用未定义。 (我想服务器脚本会在那个时候完全重新加载。)
方法 3:如果我在客户端使用 CacheService.getUserCache(),当我尝试获取缓存的 TableCell 对象时,它似乎与我设置的对象断开连接,因为我得到了迄今为止未 Google可能的错误Cannot find function getText in object TableCell.
// server, before popup is opened:
cache.put('cell_currently_being_edited', active_doc.getCursor().getElement().getParent());
// popup client calls server function like so:
google.script.run.withSuccessHandler(load_content).get_starting_content();
// server, where the above error occurs:
function get_starting_content() {
var cell_currently_being_edited = cache.get('cell_currently_being_edited');
return cell_currently_being_edited.getText();
}
如果单元格具有某种我可以传递的固定 ID 值,那可能会起作用...
我会根据单元格中的文本来做,但我希望这不是唯一的选择,因为一般的单元格文本(是的,在这个特定的上下文中也是如此)可能不是唯一的,所以在一轮之后trip 当用户激活弹出窗口时,我可能最终会替换光标所在单元格中的文本。
解决方案:
- 您可以使用单元格索引作为唯一标识符在客户端和服务器之间来回传递 RC 字符串,因为字符串值是合法的。
- 使用 Properties/Cache 服务将 RC 索引信息存储为字符串,以便将来在服务器中检索(如果需要)。
示例脚本:
function getRCTIndexOfTable(tableCell) {
var tableRow = tableCell.getParentRow();
var table = tableRow.getParentTable();
var column = tableRow.getChildIndex(tableCell);
var row = table.getChildIndex(tableRow);
var body = table.getParent().asBody();
var tableId = body.getChildIndex(table);
return 'R' + row + 'C' + column + 'T' + tableId;
}
function main() {
var active_doc = DocumentApp.getActiveDocument();
var activeTableCell = active_doc
.getCursor()
.getElement()
.getParent()
.asTableCell();
Logger.log(getRCTIndexOfTable(activeTableCell));
}
参考文献:
由于另一个答案(即使在修改代码之后)集中在问题的 "saving" 一半,我想我会分享代码,其中包括如何在之后加载引用以完成往返:
// save
var table_cell = active_doc.getCursor().getElement().getParent();
var table_row = table_cell.getParentRow();
var table = table_row.getParentTable();
var column_index = table_row.getChildIndex(table_cell);
var table_index = active_doc.getBody().getChildIndex(table);
var row_index = table.getChildIndex(table_row);
cache.put('table_currently_being_edited', table_index);
cache.put('row_currently_being_edited', row_index);
cache.put('column_currently_being_edited', column_index);
// load
function get_cell_currently_being_edited() {
var table_index = cache.get('table_currently_being_edited');
var row_index = cache.get('row_currently_being_edited');
var column_index = cache.get('column_currently_being_edited');
return active_doc.getBody().getChild(table_index).getCell(row_index, column_index);
}