传递 URL 参数和 HTML 输出执行顺序

Passing URL Arguments and HTML Output Order of Execution

这与Google Apps Script - possible charts types中的答案直接相关。

我正在尝试通过将其部署为网络应用程序而不是附加组件来扩展最佳答案,并将 URL 参数传递给应用程序脚本。

一切都与上面的 linked 示例完全相同,只是我剥离了插件代码并通过添加 doGet(e) 函数放入了最基本的 webapp 代码。

/*
//if I manually specify the values in the script, it works fine
var sheetRange = "A1:D20"; // standard range to gather data
var sheetTabName = "Sheet1"; //name of the tab in the spreadsheet to look for. must be unique
var spreadsheetId = '1CKQTQYXgt3YgnUXu0YHFeMcG5sMh99sj293oKRFVp4M'; //spreadsheet ID
*/

var sheetRange;
var sheetTabName;
var spreadsheetId;

function doGet(e) {
  //but if I try to load the arguments from the URL, it doesn't work
  //these values never get set here
  sheetRange = e.parameter.sheetRange;
  sheetTabName = e.parameter.sheetTabName;
  spreadsheetId = e.parameter.spreadsheetId;
  Logger.log("This never gets run %s %s %s",sheetRange,sheetTabName,spreadsheetId ); 

  //but this template gets made
  var template = HtmlService.createTemplateFromFile('BubbleEx')
      .evaluate()
      .setSandboxMode(HtmlService.SandboxMode.IFRAME)
      .setWidth(800)
      .setHeight(600);
  Logger.log("Why doesn't this get printed at least?");
  //and returned
  return template;
}

function getSpreadsheetData() {
  Logger.log("This does get run!\nSpreadsheetId is: %s\nSheetRange is: %s\nSheetTabName is: %s",spreadsheetId,sheetRange,sheetTabName);
  var sheet = SpreadsheetApp.openById(spreadsheetId);
  var data = sheet.getSheetByName(sheetTabName).getRange(sheetRange).getValues();
  return (data.length > 1) ? data : null;
}

很明显,我遗漏了一些关于此处执行顺序的基本信息。 HTML 与脚本交互的方式导致它在 code.gs 的某些部分完成之前完成。我 真的 不熟悉使用 GAS 作为已部署的网络应用程序,因此非常感谢 any/all 帮助。谢谢!

这是我尝试使用的预格式化 link(包含参数)。 sheet 可通过 link:

公开查看
https://script.google.com/a/macros/edmonton.ca/s/AKfycbxMbCG3p-zdoJReIS6jRHnLK3J-XsI1Zm_BFvfz_UQ/dev?spreadsheetId=1CKQTQYXgt3YgnUXu0YHFeMcG5sMh99sj293oKRFVp4M&sheetTabName=Sheet1&sheetRange=A1%3AD20

Web 应用程序中的可视化

我不久前在 a blog post 中扩展了链接问题,将仪表板示例作为 Web 应用程序。 (dashboard的代码在博客里,这里就不重复了。)

记录器使用

您在代码中留下的注释意味着您对什么-已经-运行-何时做出的结论是基于日志是否已显示。要是这么简单就好了!

不幸的是,当用于调试 Web 应用程序或其他异步操作时,Logger 是一个不可靠的工具。惊喜!这是我的 another blog post 的主题。

可以使用 BetterLog 库和一些简单的实用函数扩展 Logger,以便您可以从客户端以及异步服务器端调用生成日志。

为什么这些全局变量不起作用?

执行顺序不是问题 - 问题在于 how global variables behave between execution instances

当您在 doGet() 函数中设置 spreadsheetId 时,其内容可用于整个脚本,但仅限于 该实例执行的持续时间.在下图中,我说明了解决方案的几个部分之间的通信。每次异步调用 Google Apps 脚本函数都会创建一个新的、独立的脚本执行实例。每个实例都有自己的脚本全局变量副本。

这样做的结果是,您在 doGet() 中设置的 spreadsheetId 值在被 google.script.run 调用调用时对 getSpreadsheetData() 不可用客户端 JavaScript。 变量 仅作为一个符号存在——它并不总是同一块计算机内存。 (它甚至可能不在同一台物理计算机上。)

如果你想"set"一些"global"变量在实例之间存活,你可以使用持久存储方法,例如Properties Service。但是,在您的示例中,您会希望对此小心;如果两个用户同时访问 Web App,则最后一个访问的用户将覆盖先前用户先前设置的值。

更合适的处理方法是通过 html 模板显式传递 "globals"。 (如果您使用演示 "Web App" 模板创建新的 Google Apps 脚本,您将看到一个示例。)