fde*_*ego 4 google-docs google-sheets google-apps-script google-apps-script-addon google-apps-script-web-application
我正在将我的剧本转换成一个补充.其中一个需求是配置模板,因此我编写了一个侧栏,用于启动字段选择器.由于侧边栏没有足够的空间容纳选择器,我必须通过在侧边栏中创建的模式对话框启动它,方法是在服务器端调用此代码:
var html = HtmlService.createHtmlOutputFromFile('TemplatePicker.html')
  .setWidth(600).setHeight(425);
SpreadsheetApp.getUi().showModalDialog(html, 'Select the file with the template');
Run Code Online (Sandbox Code Playgroud)
我的问题是,一旦用户选择文件,当我拥有所选文件的ID时,我无法将该ID传递给侧边栏.我试图调用someJSFunctionOfSidebar(id)和parent.someJSFunctionOfSidebar(id),但它没有工作,所以我终于结束了值传递到服务器端,并从那里重新加载侧边栏,但它很慢,产生的效果是丑陋的.
我的问题是:
有没有办法将客户端级别的值从创建的模式对话框传递SpreadsheetApp.getUi().showModalDialog给其父级?也许这不是它的父母,这也是它不起作用的原因.
也许这不是它的父母,这也是它不起作用的原因.
对 - 这里实际上没有DOM父/子关系.侧边栏和模态对话框都是从服务器端脚本启动的,并且是独立的.但是,它们都可以与服务器通信,因此您可以使用存储转发技术将选择器的结果传递到侧边栏.
基本理念:
google.script.run.请查看如何从加载项中轮询Google文档以了解轮询器的基本概念.

尽管具有相同的起源,但侧边栏和模式对话框(兄弟)无法进行通信。
window.top即使父级是跨源的,也可以通过祖先父级从模式对话框获取对侧边栏 html 的引用。从那里,可以
window.postMessage()相互交流在没有互相引用的情况下,仍然可以通过以下方式进行通信:
window.top):addOn.html [侧边栏]
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Addon</title>
    <style>
      #spinner {
        display: none;
        background-color: tomato;
        position: absolute;
        top: 1%;
        width: 100%;
        justify-items: center;
      }
    </style>
  </head>
  <body>
    <div id="spinner"><p>Loading modal dialog...</p></div>
    <div id="output"></div>
    <script charset="utf-8">
      google.script.run.withSuccessHandler(spinner).testModal();
      function spinner(e) {
        document.getElementById('spinner').style.display = e || 'flex';
      }
      (async () => {
        //After modal dialog has finished, receiver will be resolved
        let receiver = new Promise((res, rej) => {
          window.modalDone = res;
        });
        var message = await receiver;
        document.querySelector('#output').innerHTML = message;
        //Do what you want here
      })();
    </script>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)
modalAddOn.html [模态对话框/选择器]
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title></title>
  </head>
  <body>
    Modal Dialog
    <script>
      (function findSideBar(limit) {
        let f = window.top.frames;
        for (let i = 0; i < limit; ++i) {
          try {
            if (
              f[i] /*/iframedAppPanel*/ &&
              f[i].length &&
              f[i][0] && //#sandboxFrame
              f[i][0][0] && //#userHtmlFrame
              window !== f[i][0][0] //!== self
            ) {
              console.info('Sidebar found ');
              alert('Removing loadbar and closing self');
              var sidebar = f[i][0][0];
              sidebar.spinner('none'); //Remove sidebar spinner
              sidebar.modalDone('Modal says Hi'); //Modal has finished
              google.script.host.close();
            }
          } catch (e) {
            console.error(e);
            continue;
          }
        }
      })(10);
    </script>
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)
代码.gs [服务器]
function testModal() {
  SpreadsheetApp.getUi().showModelessDialog(
    HtmlService.createHtmlOutputFromFile('modalAddOn')
      .setHeight(500)
      .setWidth(300),
    ' '
  );
}
function onOpen(e) {
  SpreadsheetApp.getUi()
    .createMenu('Sidebar')
    .addItem('Show Add-On', 'showSidebar')
    .addToUi();
}
function showSidebar() {
  SpreadsheetApp.getUi().showSidebar(
    HtmlService.createTemplateFromFile('addOn.html').evaluate()
  );
}
Run Code Online (Sandbox Code Playgroud)
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           1151 次  |  
        
|   最近记录:  |