服务器端对象传递给客户端代码时丢失

时间:2018-05-30 01:20:40

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

这与Object property values lost on server side when object passed via google.script.run

不同

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

如果我使用Run>运行以下代码作为插件测试...它显示我的菜单两次

  1. 作为名为“补充工具栏”的自定义菜单,位于“帮助”菜单旁边
  2. 作为附加菜单,在附加组件上>我的项目
    • 当我点击边栏>打开,点击侧边栏按钮getMail()会返回undefined
    • 当我点击Add-on>我的项目>打开,按预期单击侧栏按钮getMail(),返回活动的用户电子邮件地址。

    同样的情况发生,服务器端对象丢失,当我用另一个使用Spreadsheet Service来返回单元格值的@ {1}}函数时,或者甚至返回一个返回原始字符串的函数。

    我错过了什么?

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

    用作库

    的电子表格

    Code.gs

    getMail()

    Sidebar.html

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

    用于替换getMail()

    的其他函数的示例
    <!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>
    

    要用作库客户端的电子表格

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

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

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

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

    3. 作为插件测试...

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

1 个答案:

答案 0 :(得分:0)

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

解决方案是使用全局变量

用作库

的电子表格

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

要用作库客户端的电子表格

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