如何在不插入新卡片的情况下更新Google Add-On中按钮的视觉状态
解决方案
方案一:优先推荐,完全避免输入时重渲染
直接移除按钮的默认禁用状态,取消输入框的onChange监听,改为在点击发送按钮时校验内容是否为空,校验不通过直接返回提示即可,全程不需要任何输入时的卡片重绘,体验最流畅:
- 修改按钮初始化代码,移除
setDisabled(true)配置 - 改写
sendSMS方法,先校验输入内容:
function sendSMS(event) { const inputarr = event.formInputs["sms_input"]; const input = inputarr ? inputarr.join(' ').trim() : ''; if (!input) { return CardService.newActionResponseBuilder() .setNotification(CardService.newNotification().setText("请输入短信内容后再发送")) .build(); } // 原有发送短信逻辑 }
方案二:确实需要动态禁用按钮时的优化方案
Google Workspace 附加组件的Card Service设计上不支持直接修改已渲染组件的属性,所有视图更新都必须通过返回新卡片触发重绘,但可以通过以下优化完全消除卡顿感:
- 给输入框的变更动作设置禁用加载指示器,避免输入时弹出加载动画:
input.setOnChangeAction( CardService.newAction() .setFunctionName("handleInputChange") .setLoadIndicator(CardService.LoadIndicator.NONE) // 关键配置,去掉加载提示 .setParameters({ "phone": phone, "clientjson": JSON.stringify(client) }) );
- 封装独立的卡片生成方法,仅传入按钮禁用状态和当前输入内容两个参数,快速构建卡片,降低重绘开销
- 在
handleInputChange末尾返回更新后的卡片,保留用户已输入的内容:
function handleInputChange(event) { const inputarr = event.formInputs["sms_input"]; const input = inputarr ? inputarr.join(' ').trim() : ''; const sendDisabled = !input; const { phone, clientjson } = event.parameters; // 构建新卡片 const updatedCard = buildSMSCard(phone, JSON.parse(clientjson), sendDisabled, input); return CardService.newActionResponseBuilder() .setNavigation(CardService.newNavigation().updateCard(updatedCard)) .build(); } // 复用的卡片构建方法 function buildSMSCard(phone, client, sendDisabled, currentInput) { const section = CardService.newCardSection(); const input = CardService.newTextInput() .setFieldName("sms_input") .setTitle("Type in a SMS message here!") .setMultiline(true) .setValue(currentInput) .setOnChangeAction( CardService.newAction() .setFunctionName("handleInputChange") .setLoadIndicator(CardService.LoadIndicator.NONE) .setParameters({ "phone": phone, "clientjson": JSON.stringify(client) }) ); const button = CardService.newTextButton() .setText("SEND") .setTextButtonStyle(CardService.TextButtonStyle.FILLED) .setDisabled(sendDisabled); const action = CardService.newAction() .setMethodName("sendSMS") .setParameters({ "phone": phone, "clientjson": JSON.stringify(client) }); button.setOnClickAction(action); const kv = CardService.newKeyValue().setContent(' ').setButton(button); section.addWidget(input); section.addWidget(kv); return CardService.newCardBuilder().addSection(section).build(); }
内容的提问来源于stack exchange,提问作者Ramneek Singh
相关产品推荐
相关产品推荐

