首页 > 解决方案 > 使用 google.script.host.close() 时,模态对话框不会写回工作表

问题描述

我有一个非常简单的 Google Apps 脚本,用于showModalDialog()在电子表格上打开 HTML 表单。弹出窗口尝试将输入值发送回工作表,然后自行关闭。问题有时是弹出窗口的 POST 请求(称为 using google.script.run())被取消并且工作表没有更新。

错误信息

当我删除对google.script.host.close()请求的调用成功完成并更新工作表时。编辑: Arrgh,我发誓这曾经可以工作,但现在我在任何情况下都无法将数据写回工作表。但是,删除close()确实允许成功发送回调。

我尝试过使用 async/await 或成功处理程序(见问题底部),但都没有奏效。数据发送成功后如何让弹窗自动关闭?

这是服务器端代码:

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Test Menu')
      .addItem('Open Test Popup', 'showPopup')
      .addToUi();
  return false;
}

function showPopup(){
  var html = HtmlService.createTemplateFromFile('Popup').evaluate().setWidth(400).setHeight(350);
  SpreadsheetApp.getUi().showModalDialog(html, 'Test Title');
  return false;
}

function writeCustomValue(valueToWrite) {
  var sheet = SpreadsheetApp.getActive().getActiveSheet();
  var cell = sheet.getCurrentCell();
  cell.setValue(valueToWrite);
  return false;
}

这是弹出的客户端代码:

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
  </head>
  <body>    
   
    <div class="block form-group">
      <label for="valueToWrite">Write this value</label>
      <input type="text" id="valueToWrite">
    </div>
    <button id="writeResponse" onclick='writeResponse()' class="action block">Write this value</button>
        
<script>
function writeResponse(){
   document.getElementById('writeResponse').innerHTML = 'Saving ...';
   document.getElementById('writeResponse').disabled = true;
   //Get the value of the input field 
   var valueToWrite = document.getElementById('valueToWrite').value;
   //Send the value of the text field as an argument to the server side function.
   google.script.run.writeCustomValue(valueToWrite);
   google.script.host.close();
}

</script>

  </body>
</html>

这是我尝试过的:

  1. 放入host.close()成功处理程序:
google.script.run.withSuccessHandler(google.script.host.close()).writeCustomValue(valueToWrite);
  1. 异步/等待:
async function writeResponse(){
   document.getElementById('writeResponse').innerHTML = 'Saving ...';
   document.getElementById('writeResponse').disabled = true;
   //Get the value of the input field 
   var valueToWrite = document.getElementById('valueToWrite').value;
   //Send the value of the text field as an argument to the server side function.
   await google.script.run.writeCustomValue(valueToWrite);
   google.script.host.close();
}

标签: javascriptgoogle-apps-scriptgoogle-sheetsmodal-dialog

解决方案


google.script.run.withSuccessHandler将函数作为输入,这意味着您需要传入不带括号的函数名称。添加括号会传入函数的返回值,而不是函数定义。

你写了

google.script.run.withSuccessHandler(google.script.host.close()).writeCustomValue(valueToWrite);

当你的意思是

google.script.run.withSuccessHandler(google.script.host.close).writeCustomValue(valueToWrite);

相应更新后,您的代码在我的工作表中按预期运行writeResponse

至于async/await,google.script.run.writeCustomValue()不返回 Promise (它的返回类型是undefined),因此不是你能做到的await。仅添加该关键字不会更改其中的定义google.script.run或对象。运行时,你await什么也没有,脚本 * 立即移动到下一行,就好像await不在那里一样。

(* 也许“立即”是错误的词:下面的表达式 ( undefined)的值await被转换为已解决的 Promise;我将其作为练习留给读者来确定它何时会运行,但我相信效果这种情况是它在松散的意义上“立即”运行。)


推荐阅读