有关扩展GAS电子表格实用性的问题

时间:2019-06-03 10:00:40

标签: json google-apps-script three.js

我想提供一个机会,可以在电子表格的TBA边栏中,从相同数据中查看输出,例如,最好是用于创建输出的另一种HTML窗口,使用THREE之类的JavaScript库。 modeler output 我制作的non Google version是一个带有iframe的网页,该iframe可以调整大小,拖动和打开/关闭,最重要的是,它们的内容在顶部窗口中共享相同的记录对象。因此,我相信,天真的,可以在此既定且流行的应用程序中将类似的选项作为选项。 Spread output 至少,TBA试验向我展示了查看和操作sheet or TBA中的信息很有用。导航大型建筑项目,克隆房间和楼层并结合JSON记录(存储在myjson之类的存储库中)以进行协作工作的设施,对我来说尤其具有启发性。

我已经尝试过将侧边栏用于不同的HTML文件,但是事实上只有一个保持打开状态不是很有用,坦率地说,共享记录对象仍然超出了我的范围。所以这是主要问题。 Google人们是否会考虑使用额外的窗口类型可能有点雄心勃勃,但我认为值得一问。

3 个答案:

答案 0 :(得分:1)

您不能在对HtmlService的调用之间维护全局变量。触发在浏览器中运行的HtmlService实例时,启动它的服务器端代码将退出。

从这一点来看,控件是客户端,在HtmlService代码中。如果随后启动服务器端函数(从客户端使用google.script.run),则会启动服务器端脚本的新实例,而不会存储先前实例的内存-这意味着将重新初始化所有全局变量。

有许多技术可以在调用之间保持值不变。

  • 最简单的当然是首先将其传递给htmlservice,然后将其作为google.script.run的参数传递回服务器端。
  • 另一种方法是使用属性服务来保存您的值,当您返回时,它们仍然会存在,但是最大输入大小为9k
  • 如果您需要更多空间,则缓存服务可以在单个条目中容纳100k,并且您可以以相同的方式使用它(尽管极有可能将其清除-尽管这对我来说从来没有发生过)
  • 如果您需要更多空间,可以使用压缩和/或分布多个缓存条目中的单个对象的技术-如此处http://ramblings.mcpher.com/Home/excelquirks/gassnips/squuezer所述。如果您需要持久保存数据,则同样的方法也支持Google云端硬盘或Google云存储

当然,您不能传递函数等不可字符串化的对象,但是您可以推迟对它们的评估,并允许初始化的服务器端脚本来评估它们,甚至在服务器,客户端或跨项目之间共享相同的代码

这些文章中介绍了一些用于此目的的技术 http://ramblings.mcpher.com/Home/excelquirks/gassnips/nonstringify http://ramblings.mcpher.com/Home/excelquirks/gassnips/htmltemplateresuse

但是,在您的特定示例中,似乎所需的全局数据是从外部api调用中获取的。为什么不在任何情况下仅在客户端检索它?如果您需要在服务器端对其进行操作,请使用google.script.run将其传递到服务器。

答案 1 :(得分:0)

在GAS中实现全局变量的最佳方法是通过用户属性或脚本属性。https://developers.google.com/apps-script/reference/properties/properties-service。如果您只想处理一个对象,请将其写入一个对象,然后对对象进行json.stringify(和json.parse以将其取回)。

答案 2 :(得分:0)

window.open window.postMessage()解决了上述两个问题。

我希望您可以从屏幕截图和代码中放心,可以将Google表格的用途扩展到实现共同利益的目的。核心是两种输入,复制和审阅文本数据的方法-电子表格以通过一组数据的切片,TBA用于在Trail(x轴)和Branchs(y轴)中关联的导航以及当前选择的各个方面(z轴)需要来自不同兴趣的协作关注。

screenshot showing TBA and monitor window

因此,例如,护士会发现TBA对于记录患者检查的许多方面都很有用,而药剂师可能会发现电子表格对库存控制更有用。两者都将数据记录在一个我称为“ nset”(命名集的层次结构)的通用对象中,并保存在云中并可以在协作活动中分发。

TBA对克隆大量记录也很有用。例如,一个带有家具的房间可以在一个楼层上复制,然后可以将那个带有房间的地板复制为一个完整的塔。

通过postMessage能够在多个监视器窗口中维护并行的nset对象,意味着无与伦比的机会以不同形式的多媒体显示相同的数据,包括交互式动画,增强现实,CNC机器指令,物联网控件...

这是相关代码:

在边栏中的TBA中:

 window.addEventListener("message", receiveMessage, false);

    function openMonitor(nset){
       var params = [
          'height=400',
          'width=400'
       ].join(',');
        let file = 'http://glasier.hk/blazer/model.html';
        popup = window.open(file,'popup_window', params); 
        popup.moveTo(100,100);
      }

    var popup;

    function receiveMessage(event) {
      let ed,nb;
      ed = event.data;
      nb = typeof ed === "string"? ed : nb[0];
      switch(nb){
        case "Post":
          console.log("Post");
          popup.postMessage(["Refreshing nset",nset], "http:glasier.hk"); 
          break;
        }
    }

        function importNset(){
          google.script.run
          .withSuccessHandler(function (code) {
           root = '1grsin';
           trial = 'msm4r';
           orig = 'ozs29';
           code = orig;
            path = "https://api.myjson.com/bins/"+code;
            $.get(path)
            .done((data, textStatus, jqXHR) => {
              nset = data;
              openMonitor(nset);
              cfig = nset.cfig;
              start();
              })
          })
          .sendCode();
        }

在弹出窗口中:

     $(document).ready(function(){
        name = $(window).attr("name");
        if(name === "workshop"){
          tgt = opener.location.href;
        }
        else{
          tgt = "https://n-rxnikgfd6bqtnglngjmbaz3j2p7cbcqce3dihry-0lu-script.googleusercontent.com"
        }
        $("#notice").html(tgt);
        opener.postMessage("Post",tgt);
        $(window).on("resize",function(){
          location.reload();
        })
      })
    }

    window.addEventListener("message", receiveMessage, false);

    function receiveMessage(event) {
      let ed,nb;
      ed = event.data;
      nb = typeof ed === "string"? ed : ed[0];
      switch(nb){
        case "Post": popup.postMessage(["nset" +nset], "*"); break;
        default :
        src = event.origin;
        notice = [ed[0]," from ",src ];
        console.log(notice);
       // $("#notice").html(notice).show();
        nset = ed[1];
        cfig = nset.cfig;
        reloader(src);
      }
    }

我应该解释,侧边栏的html部分是在localhost工作坊上构建的,所有样式和脚本都被编译到一个文件中以粘贴到侧边栏html文件中。该研讨会也online可用。 Google目标由postMessage中的event.origin提供。这将必须发布给希望制作不同监视器的任何人。现在,我刚刚使用Three.js制作了3D建模监视器。

我认为,在这里进行了大量研究和质疑之后,这应该是正确的答案。