将URL参数传递到Web App脚本中

时间:2016-03-02 04:34:41

标签: javascript google-apps-script parameters

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

  

TypeError:无法读取属性"参数"来自undefined。 (第2行,文件" Code",project" singleStory")

下面是我的Code.gs和Index.html文件(项目不完整。这就是我到目前为止的地方。)

Code.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();
 }
}

的index.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>

我用来测试的网址+参数是:

https://script.google.com/a/macros/--DOMAIN--/s/--SCRIPTID--/exec?story=3

有人可以就我们为什么不工作给我一些想法吗?

1 个答案:

答案 0 :(得分:1)

  

TypeError:无法读取属性&#34;参数&#34;来自undefined。 (第2行,文件&#34; Code&#34;,project&#34; singleStory&#34;)

这告诉您希望包含命名属性的对象&#34;参数&#34;未定义。

查看您的代码(e.parameter.story),该代码引用了事件参数e。对于那些不熟悉这一点的人,当在部署的Web应用程序中调用它时,特别命名的doGet()函数会收到event parameter,在此示例中名为e。)

为什么e在这里未定义?

您可能会看到这一点的一个原因是,您是否正在从调试器运行该功能,而不是将其作为Web应用程序进行测试。凯文,这不是你的情况,因为你在浏览器中输入了一个URL来尝试启动网络应用程序。

问题最终出现在Templated HTML。 HTML中的第一个语句是:

<? var data = doGet(); ?>

一旦我们尝试.evaluate()模板,这会导致麻烦,因为它重新调用doGet()函数,这次没有任何事件对象。并且 时间周围会发出错误消息。

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

<? var data = getData(); ?>

随着更改的到位,您现在会收到事件参数e(您总是这样做...)并且代码会继续。直到下一个错误:

  

ReferenceError:&#34; i&#34;没有定义。 (第3行,文件&#34;代码&#34;)

现在事情变得棘手了,因为在Code.gs中报告了这个错误:

return HtmlService
    .createTemplateFromFile('Index')
    .evaluate()
    .setSandboxMode(HtmlService.SandboxMode.IFRAME);

但是等等!在第2行中没有定义i?是的,它是......但是这个错误大约是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()'

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

  • 阻止您的功能是错误的,您希望getData()在全球范围内,而不是doGet()
  • 您可能需要调试模板,请遵循Debugging templates中的指导。
  • 模板化代码附有<? thusly ?>,而不是<?= like this ?>