我有以下代码创建一个简单的应用程序,允许用户输入两个值并单击按钮:
function start() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication();
app.setTitle("Appraisals Analysis");
app.setHeight(100);
app.setWidth(500);
var grid = app.createGrid(3, 2);
grid.setId("grid");
grid.setCellSpacing(2);
grid.setCellPadding(2);
var uafLabel = app.createLabel("Unprocessed apparaisals folder name: ");
uafLabel.setStyleAttributes({"font-weight": "bold"});
var uafTextBox = app.createTextBox();
uafTextBox.setName('uafTextBox').setId('uafTextBox');
uafTextBox.setText('Unprocessed Appraisals');
grid.setWidget(0, 0, uafLabel);
grid.setWidget(0, 1, uafTextBox);
var pafLabel = app.createLabel("Processed apparaisals folder name: ");
pafLabel.setStyleAttributes({"font-weight": "bold"});
var pafTextBox = app.createTextBox();
pafTextBox.setName('pafTextBox').setId('pafTextBox');
pafTextBox.setText('Processed Appraisals');
grid.setWidget(1, 0, pafLabel);
grid.setWidget(1, 1, pafTextBox);
var button = app.createButton('Submit').setId("submitButton");
grid.setWidget(2, 0, button);
var mypanel = app.createVerticalPanel();
mypanel.add(grid);
app.add(mypanel);
var clickHandler = app.createServerClickHandler("parseFiles");
button.addClickHandler(clickHandler);
clickHandler.addCallbackElement(grid);
ss.show(app);
}
然后我有了parseFiles函数,它可能需要2分钟来完成它的工作,如下所示
function parseFiles(e) {
var app = UiApp.getActiveApplication();
var processedFolder = DocsList.getFolder(e.parameter.pafTextBox);
var workingFolder = DocsList.getFolder(e.parameter.uafTextBox);
var appraisals = workingFolder.find('Performance Appraisal');
app.getElementById("submitButton").setText("Parsing Files...");
for (var i in appraisals) {
var doc = DocumentApp.openById(appraisals[i].getId());
parseDocument(doc, getEmpName(doc.getName()));
}
return app;
}
我的问题是,当我点击按钮时,工作完成,但按钮文字保持为"提交"而不是改为"解析文件..."。一旦工作结束,按钮就会改变。
知道我可能做错了吗?
此致 Crouz
答案 0 :(得分:1)
你没有错,只是概念。这样想:您编写的所有Apps脚本代码都在谷歌服务器(服务器端)上运行,但是(明显地)显示在您的计算机(客户端)上。 Apps脚本“环境”有一个客户端脚本(我们无权访问或控制),它接收有关如何构建您在代码(服务器端)中定义的接口的信息。
因此,在函数完成后,您在代码中执行的所有操作都会立即更新。这就是为什么我们需要return app
,以便我们的UiApp
定义被发送/返回到已触发脚本的客户端。
对于非常简单的情况,例如禁用或设置按钮或标签上的文本,有一个clientHandler可以直接在客户端执行基本操作,而无需网络访问服务器端来运行你的自定义代码。由于这些操作是在客户端完成的,因此它们“立即”完成。请注意,这不是针对通用代码,而是针对预定义操作。 clientHandler
只是简单的东西。做复杂的操作很困难(如果不是不可能的话)。
以下是我使用clientHandler
:
function start() {
//your current code...
clickHandler.addCallbackElement(grid);
var clientHandler = app.createClientHandler().forEventSource().setText('Parsing Files...').setEnabled(false);
button.addClickHandler(clientHandler);
ss.show(app);
}
function parseFiles(e) {
//...
app.getElementById("submitButton").setText("Submit again").setEnabled(true);
//...
return app;
}
请注意,您可以向按钮(或任何其他接受处理程序的小部件)添加多个处理程序,客户端或服务器,并且所有这些都将同时运行。
另外,请注意我们在这里谈论UiApp
非常重要,在使用HtmlService
时,这种方法会有很大不同。