使用 google.script.host.close() 时,模态对话框不会写回 sheet

Modal dialog doesn't write back to sheet, when google.script.host.close() is used

我有一个非常简单的 Google Apps 脚本,它使用 showModalDialog() 打开跨页 HTML 表单 sheet。弹出窗口尝试将输入值发送回 sheet,然后自行关闭。问题是 有时 弹出窗口的 POST 请求(使用 google.script.run() 调用)被取消并且 sheet 没有更新。

当我删除对 google.script.host.close() 的调用时,请求成功完成并且 sheet 已更新。 编辑: 啊,我发誓这曾经有效,但现在我在任何情况下都无法将数据写回 sheet。不过,删除 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/await:
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();
}

google.script.run.withSuccessHandler接受一个函数作为输入,这意味着你需要传入函数的名称不带括号。添加括号传入函数 的 return 值,而不是函数定义。

你写了

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

你的意思是

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

在相应地更新 writeResponse 后,您的代码 运行 在我的 Sheet 中符合预期。

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

(* 也许“立即”是错误的词:the value of the expression (undefined) following await is converted into a resolved Promise;我把它留给 reader 作为练习,以找出 确切地 什么时候它会 运行,但我相信在这种情况下的效果是 运行 在松散意义上“立即”。)