google-apps-script - 传递给客户端代码时服务器端对象丢失
问题描述
这与通过 google.script.run 传递对象时在服务器端丢失的 Object 属性值不同
我正在尝试设置我的 Google Apps 脚本插件测试框架。由于 Test as add-on 不能用于测试可安装的触发器,我想知道是否可以从有界项目中提取服务器端代码以用作库来测试调用服务器端函数的边栏。
如果我使用 Run > Test 作为附加组件运行以下代码...它会显示我的菜单两次
- 作为名为“侧边栏”的自定义菜单,位于帮助菜单旁边
- 作为附加菜单,在附加组件 > 我的项目
- 当我单击侧边栏 > 打开时,单击侧边栏按钮会
getMail()
返回undefined
- 当我单击 Add-on > My Project > Open 时,单击侧边栏按钮
getMail()
,如预期的那样,返回活动用户电子邮件地址。
同样的情况,服务器端对象丢失,当我用getMail()
另一个使用电子表格服务返回单元格值的函数,甚至是返回原始字符串的函数替换该函数时。
我错过了什么?
底线是我想在我的侧边栏添加一个按钮,该按钮创建一个可安装的触发器并从电子表格中获取一些值。
用作库的电子表格
代码.gs
function onOpen(e) {
var ui = SpreadsheetApp.getUi();
var menu = ui.createMenu('Sidebar');
menu
.addItem('Open', 'showSidebar')
.addToUi();
}
function showSidebar() {
var ui = HtmlService.createHtmlOutputFromFile('Sidebar')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('A Sidebar');
SpreadsheetApp.getUi().showSidebar(ui);
}
function getEmail() {
return Session.getActiveUser().getEmail();
}
边栏.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script>
function updateButton(email, button) {
console.log(email);
button.value = 'Clicked by ' + email;
}
</script>
</head>
<body>
<input type="button" value="Not Clicked" onclick="google.script.run
.withSuccessHandler(updateButton)
.withUserObject(this)
.getEmail()" />
<input type="button" value="Not Clicked" onclick="google.script.run
.withSuccessHandler(updateButton)
.withUserObject(this)
.getEmail()" />
</body>
</html>
用于替换 getMail() 的其他函数示例
function getCellValue(){
return SpreadsheetApp.getActiveCell().getValue();
}
function getGreeting(){
return 'Hello world';
}
用作图书馆客户端的电子表格
- 将库添加到项目中
添加以下代码
函数 onOpen(e) { aLib.onOpen(e); }
函数 showSidebar(){ aLib.showSidebar(); }
函数 getEmail(){ aLib.getEmail(); }
作为插件测试...
- 单击运行 > 测试作为附加组件
- 将“电子表格用作库客户端”添加为用于测试附加组件的文档
- 启动文档
解决方案
根据https://developers.google.com/apps-script/guides/html/communication#private_functions google.script 无法访问库函数,但看起来它也无法访问库对象。
解决方案是使用全局变量
用作库的电子表格
代码.gs
/* For tests only, assign the server side function
* to be called from the sidebar to a global variable
*/
var email = getEmail();
/**
* Reference: https://stackoverflow.com/q/50595103/1595451
*
*/
function onOpen(e) {
var ui = SpreadsheetApp.getUi();
var menu = ui.createMenu('Sidebar');
menu
.addItem('Open', 'showSidebar')
.addToUi();
}
function showSidebar() {
var ui = HtmlService.createHtmlOutputFromFile('Sidebar')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('A Sidebar');
SpreadsheetApp.getUi().showSidebar(ui);
}
function getEmail() {
return Session.getActiveUser().getEmail();
}
用作图书馆客户端的电子表格
代码.gs
var email = aLib.email;
function onOpen(e) {
aLib.onOpen(e);
}
function showSidebar(){
aLib.showSidebar();
}
function getEmail(){
/* Instead of calling the library function we call the library global variable */
return email;
}
推荐阅读
- firebase - 如何从异常 try catch 中返回并显示错误消息
- java - 无论我尝试什么,片段上的按钮都不会链接到另一个活动
- python - 如何将 jupyterhub 小部件创建为对象?
- python - docker-compose 忽略已安装的 django、virtualenv
- java - JpaSpecificationExecutor的方法是怎么做的
.findAll(规范 规范)有效吗? - tensorflow - 如何在 tensorflow lite 模型文件 (v 1.x) 中嵌入模型版本或描述
- python - 如何在 Pyqt 中创建可调整大小的布局 UI?
- javascript - Chrome扩展打开多个标签
- windows-installer - 如何在使用 VS2017 设置项目创建设置时在对话框中添加自定义先决条件?
- java - JPA 与 netbeans 8.2