【问题标题】:Server side object lost when passed to client side code传递给客户端代码时服务器端对象丢失
【发布时间】:2018-05-30 01:20:39
【问题描述】:

这和Object property values lost on server side when object passed via google.script.run不一样

我正在尝试设置我的 Google Apps 脚本插件测试框架。由于 Test as add-on 不能用于测试可安装的触发器,我想知道是否可以从有界项目中提取服务器端代码以用作库来测试调用服务器端函数的边栏。

如果我使用 Run > Test 作为附加组件运行以下代码...它会显示我的菜单两次

  1. 作为一个名为“侧边栏”的自定义菜单,位于帮助菜单旁边
  2. 作为插件菜单,在插件 > 我的项目中
  • 当我单击侧边栏 > 打开时,单击侧边栏按钮 getMail() 返回 undefined
  • 当我点击插件 > 我的项目 > 打开时,点击侧边栏按钮 getMail(),正如预期的那样,返回活动用户电子邮件地址。

当我将getMail() 函数替换为另一个使用电子表格服务返回单元格值或什至返回原始字符串的函数时,同样会发生服务器端对象丢失。

我错过了什么?

最重要的是,我想在我的侧边栏添加一个按钮,该按钮创建一个可安装的触发器并从电子表格中获取一些值。

用作库的电子表格

代码.gs

function onOpen(e) {
  var ui = SpreadsheetApp.getUi();
  var menu = ui.createMenu('Sidebar');
  menu
    .addItem('Open', 'showSidebar')
    .addToUi();
}

function showSidebar() {
  var ui = HtmlService.createHtmlOutputFromFile('Sidebar')
    .setSandboxMode(HtmlService.SandboxMode.IFRAME)
    .setTitle('A Sidebar');
  SpreadsheetApp.getUi().showSidebar(ui);

}

function getEmail() {
  return Session.getActiveUser().getEmail();
}

边栏.html

<!DOCTYPE html>
<html>

<head>
  <base target="_top">
  <script>
    function updateButton(email, button) {
      console.log(email);
      button.value = 'Clicked by ' + email;
    }
  </script>
</head>

<body>
  <input type="button" value="Not Clicked" onclick="google.script.run
          .withSuccessHandler(updateButton)
          .withUserObject(this)
          .getEmail()" />
  <input type="button" value="Not Clicked" onclick="google.script.run
          .withSuccessHandler(updateButton)
          .withUserObject(this)
          .getEmail()" />
</body>

</html>

用于替换getMail()的其他函数示例

function getCellValue(){
  return SpreadsheetApp.getActiveCell().getValue();
}

function getGreeting(){
  return 'Hello world';
}

用作库客户端的电子表格

  1. 将库添加到项目中
  2. 添加以下代码

    函数 onOpen(e) { aLib.onOpen(e); }

    函数 showSidebar(){ aLib.showSidebar(); }

    函数getEmail(){ aLib.getEmail(); }

作为插件测试...

  1. 点击运行 > 作为插件测试
  2. 将“电子表格用作库客户端”添加为用于测试插件的文档
  3. 启动文档

【问题讨论】:

  • 在我的环境中,很遗憾,您的情况无法重现。我做了如下。 1. 创建电子表格和绑定脚本。 2. 将你的脚本放到绑定脚本中。 3. 运行 > 测试作为附加组件。但是打开的电子表格没有“侧边栏”菜单,只有加载项>我的项目>打开。如果我误解了你的问题,你能告诉我吗?对了,用SpreadsheetApp.getUi().createAddonMenu().addItem('Open', 'showSidebar').addToUi()添加菜单怎么样?
  • @Tanaike Testa 作为插件需要设置一个文件,使用有界电子表格进行测试。稍后我会为问题添加更多细节。
  • @Tanaike 对不起。我刚刚意识到我遗漏了一些细节。更新我的问题需要的时间比我想象的要长。
  • 感谢您的回复。没问题。

标签: google-apps-script google-sheets google-apps-script-addon


【解决方案1】:

根据https://developers.google.com/apps-script/guides/html/communication#private_functionsgoogle.script 无法访问库函数,但看起来它也无法访问库对象。

解决办法是使用全局变量

用作库的电子表格

代码.gs

/* For tests only, assign the server side function
 * to be called from the sidebar to a global variable 
 */
var email = getEmail(); 

/**
 * Reference: https://stackoverflow.com/q/50595103/1595451
 *
 */
function onOpen(e) {
  var ui = SpreadsheetApp.getUi();
  var menu = ui.createMenu('Sidebar');
  menu
    .addItem('Open', 'showSidebar')
    .addToUi();
}

function showSidebar() {
  var ui = HtmlService.createHtmlOutputFromFile('Sidebar')
    .setSandboxMode(HtmlService.SandboxMode.IFRAME)
    .setTitle('A Sidebar');
  SpreadsheetApp.getUi().showSidebar(ui);

}

function getEmail() {
  return Session.getActiveUser().getEmail();
}

用作库客户端的电子表格

代码.gs

var email = aLib.email;

function onOpen(e) {
  aLib.onOpen(e);
}

function showSidebar(){
  aLib.showSidebar();
}

function getEmail(){
  /* Instead of calling the library function we call the library global variable */
  return email; 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多