将 URL 参数传递到 Web 应用程序脚本中

Kev*_*inH 5 javascript parameters google-apps-script

这个问题让我想拔掉头发。我正在尝试将 URL 参数传递给 Google Apps 脚本,其中包含我想要呈现的数据的行 ID(来自电子表格)。我的参数是story. 但是,无论我尝试什么,我都会遇到各种各样的错误。最新的是:

类型错误:无法从未定义中读取属性“参数”。(第 2 行,文件“Code”,项目“singleStory”)

下面是我的 Code.gs 和 Index.html 文件(该项目尚未完成。这正是我目前所处的位置。)

代码.gs

function doGet(e) {
    var i = e.parameter.story;
    return HtmlService
      .createTemplateFromFile('Index')
      .evaluate()
      .setSandboxMode(HtmlService.SandboxMode.IFRAME);

 function getData() {
 return SpreadsheetApp
      .openById("1Z582cnr03fkLC7xCca4pcj7QwDtSCS4KGneyFKMgdyo")
      .getSheetByName("StoryTopics")
      .getDataRange()
      .getValues();
 }
}
Run Code Online (Sandbox Code Playgroud)

索引.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
  <? var data = doGet(); ?>

<div id="container">
<div id="header">
<div id="topicname">
    <?= data[i][0] ?>
</div>
<div id="todaysdate">
<p>As of: <?= new Date() ?></p>
</div>
<div id="topictype">
<?= data[i][1] ?>
</div>
<div id="locale">
<?= data[i][2] ?>
</div>
</div>
<div id="contact_container">
<div id="subheader">
</div>
<div id="contact_name">
<?= data[i][3] ?>
</div>
<div id="contact_title">
<?= data[i][4] ?>, <?= data[i][5] ?>
</div>
<div id="contact_email">
<?= data[i][6] ?>
</div>
<div id="contact_phone">
<?= data[i][7] ?>
</div>
</div>
<div id="action_container">
<div id="subheader">
</div>
<table id="action_table">
<tr>
<td>
Date:
</td>
<td>
Type:
</td>
<td>
Description:
</td>
</tr>
</table>
</div>
<div id="story_container">
<div id="story_title">
</div>
<div id="story_content">
</div>
</div>
</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

我用来测试的 URL + 参数是:

https://script.google.com/a/macros/--DOMAIN--/s/--SCRIPTID--/exec?story=3
Run Code Online (Sandbox Code Playgroud)

谁能给我一些关于为什么它不起作用的想法?

Mog*_*dad 6

类型错误:无法从未定义中读取属性“参数”。(第 2 行,文件“Code”,项目“singleStory”)

这告诉您,您期望包含命名属性“parameter”的对象未定义。

查看您的代码 ( e.parameter.story),它指的是事件参数e。对于那些不熟悉这一点的人来说,当在已部署的 Web 应用程序中调用它时,专门命名的doGet()函数会收到一个事件参数e(在此示例中命名)。

为什么e这里未定义?

您可能会看到这种情况的原因之一是,您是否从调试器运行该函数,而不是将其作为 Web 应用程序进行测试。Kevin,这不是您的情况,因为您正在浏览器中输入 URL 来尝试启动 Web 应用程序。

问题出在模板化 HTML中。HTML 中的第一条语句是:

<? var data = doGet(); ?>
Run Code Online (Sandbox Code Playgroud)

当我们尝试使用.evaluate()模板时,这会导致麻烦,因为它重新调用该doGet()函数,这次没有任何事件对象。正是在这个时候,错误消息被吐出来了。

您可能打算这样做,而不是从电子表格中获取数据:

<? var data = getData(); ?>
Run Code Online (Sandbox Code Playgroud)

完成此更改后,您现在会收到事件参数e(您总是这样做......)并且代码将继续运行。直到下一个错误:

ReferenceError:“i”未定义。(第 3 行,文件“代码”)

现在事情变得棘手,因为根据 Code.gs 中的此语句报告错误:

return HtmlService
    .createTemplateFromFile('Index')
    .evaluate()
    .setSandboxMode(HtmlService.SandboxMode.IFRAME);
Run Code Online (Sandbox Code Playgroud)

可是等等!不是i在第2行定义的吗?是的,它是...但是这个错误是关于evaluate()尝试填写模板,而您的代码尚未为此设置i。您需要分解此语句以首先获取模板,然后为其设置参数,最后对其进行评估。像这样:

function doGet(e) {
  var i = e.parameter.story;

  // First, get the template
  var template = HtmlService.createTemplateFromFile('Index');

  // Second, set template parameters
  template.i = i;

  // Finally, evaluate() the template
  return template.evaluate()
                 .setSandboxMode(HtmlService.SandboxMode.IFRAME);

}  // <-- You had this on the other side of 'getData()'
Run Code Online (Sandbox Code Playgroud)

那应该会让你滚动。您还有其他错误:

  • 你的函数的阻塞是错误的,你想要getData()在全局范围内,而不是在doGet().
  • 您可能需要调试模板,请按照调试模板中的指导进行操作。
  • 模板代码是附上的<? thusly ?>,而不是<?= like this ?>