如何在Google Workspace插件中重新赋值Google App Script全局变量?
问题描述
在Google Apps Script中尝试重新赋值全局变量myname,点击「Set Name」按钮后,handleSetName函数里已将myname设为"Testing Name",控制台能看到赋值成功,但调用handleGetName函数获取时却显示undefined。
代码示例
var myname = ""; function loadMTS(event) { const button1 = CardService.newTextButton().setText("Set Name") .setTextButtonStyle(CardService.TextButtonStyle.FILLED) .setOnClickAction(CardService.newAction().setFunctionName("handleSetName")); const button2 = CardService.newTextButton().setText("Get Name") .setTextButtonStyle(CardService.TextButtonStyle.FILLED) .setOnClickAction(CardService.newAction().setFunctionName("handleGetName")); return card.addSection(CardService.newCardSection().addWidget(button1).addWidget(button2)).build(); } function handleSetName(e) { myname = "Testing Name"; console.log("Name after change in handleSetName Fucntion :", myname); } function handleGetName(e) { console.log("Name : ", myname); }
控制台输出截图

问题原因与解决办法
核心原因
Google Apps Script的每个函数调用都是独立的运行实例,全局变量的作用域只限于当前函数执行的会话。点击「Set Name」触发handleSetName时,变量myname在这个会话里被修改,但会话结束后值就会被销毁;再点击「Get Name」触发handleGetName时,会开启全新会话,此时全局变量myname会被重新初始化为空字符串,所以输出undefined。
解决办法
要在不同函数调用间共享数据,需要使用Google Apps Script提供的持久化存储或会话状态传递方案:
方案1:使用PropertiesService持久化存储
这是最常用的跨会话数据共享方式,根据数据的访问范围选择不同的属性存储:
function loadMTS(event) { const button1 = CardService.newTextButton().setText("Set Name") .setTextButtonStyle(CardService.TextButtonStyle.FILLED) .setOnClickAction(CardService.newAction().setFunctionName("handleSetName")); const button2 = CardService.newTextButton().setText("Get Name") .setTextButtonStyle(CardService.TextButtonStyle.FILLED) .setOnClickAction(CardService.newAction().setFunctionName("handleGetName")); return CardService.newCardBuilder().addSection(CardService.newCardSection().addWidget(button1).addWidget(button2)).build(); } function handleSetName(e) { // 用用户属性存储,仅当前用户可见 PropertiesService.getUserProperties().setProperty("myname", "Testing Name"); console.log("Name after change in handleSetName Fucntion :", PropertiesService.getUserProperties().getProperty("myname")); } function handleGetName(e) { const myname = PropertiesService.getUserProperties().getProperty("myname"); console.log("Name : ", myname); }
getUserProperties():数据仅当前用户可见,适合私有数据getDocumentProperties():数据对所有有权限访问文档/脚本的用户可见getScriptProperties():数据对脚本所有用户可见,适合全局配置
方案2:使用卡片状态传递数据(仅会话内有效)
如果只需要在当前卡片交互过程中共享数据,可以通过ActionResponse更新卡片状态:
function loadMTS(event) { // 从事件参数获取已存储的名称,初始为空 const currentName = event.parameters?.myname || ""; const button1 = CardService.newTextButton().setText("Set Name") .setTextButtonStyle(CardService.TextButtonStyle.FILLED) .setOnClickAction(CardService.newAction() .setFunctionName("handleSetName") .setParameters({myname: "Testing Name"})); const button2 = CardService.newTextButton().setText("Get Name") .setTextButtonStyle(CardService.TextButtonStyle.FILLED) .setOnClickAction(CardService.newAction() .setFunctionName("handleGetName") .setParameters({myname: currentName})); return CardService.newCardBuilder().addSection(CardService.newCardSection().addWidget(button1).addWidget(button2)).build(); } function handleSetName(e) { const updatedName = e.parameters.myname; console.log("Name after change in handleSetName Fucntion :", updatedName); // 返回更新后的卡片,携带状态参数 return CardService.newActionResponseBuilder() .setNavigation(CardService.newNavigation().updateCard(loadMTS(e))) .build(); } function handleGetName(e) { const myname = e.parameters.myname; console.log("Name : ", myname); }
内容的提问来源于stack exchange,提问作者Shiv Yadav
相关产品推荐
相关产品推荐

