我想提供一个机会,可以在电子表格的TBA边栏中,从相同数据中查看输出,例如,最好是用于创建输出的另一种HTML窗口,使用THREE之类的JavaScript库。 我制作的non Google version是一个带有iframe的网页,该iframe可以调整大小,拖动和打开/关闭,最重要的是,它们的内容在顶部窗口中共享相同的记录对象。因此,我相信,天真的,可以在此既定且流行的应用程序中将类似的选项作为选项。 至少,TBA试验向我展示了查看和操作sheet or TBA中的信息很有用。导航大型建筑项目,克隆房间和楼层并结合JSON记录(存储在myjson之类的存储库中)以进行协作工作的设施,对我来说尤其具有启发性。
我已经尝试过将侧边栏用于不同的HTML文件,但是事实上只有一个保持打开状态不是很有用,坦率地说,共享记录对象仍然超出了我的范围。所以这是主要问题。 Google人们是否会考虑使用额外的窗口类型可能有点雄心勃勃,但我认为值得一问。
答案 0 :(得分:1)
您不能在对HtmlService的调用之间维护全局变量。触发在浏览器中运行的HtmlService实例时,启动它的服务器端代码将退出。
从这一点来看,控件是客户端,在HtmlService代码中。如果随后启动服务器端函数(从客户端使用google.script.run),则会启动服务器端脚本的新实例,而不会存储先前实例的内存-这意味着将重新初始化所有全局变量。
有许多技术可以在调用之间保持值不变。
当然,您不能传递函数等不可字符串化的对象,但是您可以推迟对它们的评估,并允许初始化的服务器端脚本来评估它们,甚至在服务器,客户端或跨项目之间共享相同的代码
这些文章中介绍了一些用于此目的的技术 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轴)需要来自不同兴趣的协作关注。
因此,例如,护士会发现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建模监视器。
我认为,在这里进行了大量研究和质疑之后,这应该是正确的答案。