【问题标题】:Control Flow Between Server and Client and Back to Server for Google Apps Script用于 Google Apps 脚本的服务器和客户端之间以及返回服务器的控制流
【发布时间】:2018-02-21 08:18:22
【问题描述】:

我有一个关于在谷歌电子表格中作为绑定函数运行的一些 JavaScript 代码 - 所以是服务器端 - 和作为客户端的对话框(恰好是模态,但无模态是相同的)之间的控制流的问题。

虽然下面的代码示例工作正常,因为对话框按照下面的行成功调用了服务器端函数,并且 withSuccessHandler 也可以工作。

google.script.run.withSuccessHandler(success_callback).getCredentials(this.parentNode)

但我真正想要实现的是,一旦对话结束,一些服务器端代码继续执行;理想情况下,从调用 .showModalDialog() 函数的那一刻起,我很乐意将控制权交还给任何服务器端函数。

下面是一些示例软件;不要忘记这是有效的,只是不是我想要的!本质上,由 OnOpen() 函数创建的菜单项的事件处理程序调用模式对话框来提示用户输入安全凭证。

var html = HtmlService.createHtmlOutputFromFile('authorization_dialog');
      SpreadsheetApp.getUi() 
          .showModalDialog(html, 'Authorization Dialog');

HTML 文件:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>

  <body>
    <form>    
        Authorization Code:&nbsp;&nbsp;
        <input type="text" name="authorization_code"><br><br>
        Account ID:&nbsp;&nbsp;
        <input type="text" name="account_id"><br><br>
        Enter account details...
        <br>
        <br><br>
        <input type="button" value="OK"
             onclick="google.script.run.withSuccessHandler(success_callback).getCredentials(this.parentNode)" />    
        <input type="button" value="Close"
             onclick="google.script.host.close()" />

    </form>

    <script>

       // Using this call back prevents the need to hit the Close Button after OK.
       function success_callback() {
         google.script.host.close(); // Close the dialog.
       }
    </script>
  </body>
</html>

【问题讨论】:

    标签: google-apps-script


    【解决方案1】:

    如果您不需要来自服务器端函数的响应,只需省略 'withSuccessHandler';

    function func_client(){
    
    google.script.run.func_server();
    google.script.host.close();
    
    
    }
    

    在这种情况下,服务器端代码将继续执行而不锁定客户端的 UI - 您可以调用 'func_server' 中的任何其他函数。

    如果您想处理来自第一个函数调用的响应,请从“success_callback”调用第二个函数。该对话框将在不等待 google.script.run 完成的情况下关闭,但服务器代码将继续执行。 在下面的示例中,第一个服务器函数将表单数据传回客户端,其中“success_callback”立即调用另一个需要一段时间才能完成的服务器函数(它将每个文件记录在我的 Google Drive 中);

    客户:

     <form id="form">
        .....
            <input type="submit" id="ok" value="OK" />    
            <input type="button" value="Close" onclick="google.script.host.close()" />    
        .....
       </form>
    
    <script>
       window.onload = function(){
    
        document.getElementById("form")
                .addEventListener("submit", function(e){
    
        e.preventDefault();
    
        google.script.run
                     .withSuccessHandler(success_callback)
                     .logFormData(this);
    
    });
    
    
    }
    
       function success_callback(response) {
    
         console.log(response);
    
         google.script.run.scanFiles();
         google.script.host.close(); // Close the dialog.
       }
    </script>  
    

    服务器:

    function showDialog(){
    
    var ui = SpreadsheetApp.getUi();
    
    //IMPORTANT: client-side scripts won't be executed 
    //without calling evaluate() on the HtmlTemplate object before passing it to UI;
    
    var template = HtmlService.createTemplateFromFile("dialog");
    var html = template.evaluate();
    
    ui.showModalDialog(html, "dialog");
    
    
    }
    
    
    function logFormData(formData){
    
    
    return formData;
    
    }
    
    
    function scanFiles() {
    
    var files = DriveApp.getFiles();
    var file;  
    
      while (files.hasNext()) {
    
      file = files.next();
    
        Logger.log(file.getName() + ": " + file.getMimeType());
    
    
      }
    
    
    }
    

    【讨论】:

    • 安东,谢谢。你帮我确定了发生了什么。对其他人的警告:Logger.Log() 在尝试跟踪此类代码的执行时没有多大用处,因为从客户端对话框调用的每个服务器端函数似乎都会重置 Log 覆盖什么已经在那里了。所以 Logger 不会告诉你实际运行了哪些服务器端函数;只是最后一个。通过写入电子表格单元格来跟踪函数调用。由于上述原因,我错过了 showModelDialog() 调用实际上并没有阻塞,这是我困惑的根源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2019-02-01
    相关资源
    最近更新 更多