刷新按钮的文本不适用于GAS

时间:2014-05-20 15:51:48

标签: google-apps-script

我有以下代码创建一个简单的应用程序,允许用户输入两个值并单击按钮:

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

1 个答案:

答案 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时,这种方法会有很大不同。