1

我正在编写一个 Web 应用程序,它显示电子表格工作表中的行子集。为了方便用户,数据以网格形式呈现,从电子表格中选择的每一行在网格中形成一行。与每个用户相关的行数会随着时间的推移而增长。

网格的标题是一组按钮,允许用户控制数据的排序顺序。因此,如果用户单击第一列标题中的按钮,则填充网格的数组将按第一列排序,依此类推。如果您单击同一列按钮两次,则排序顺序会颠倒。

我使用脚本属性在响应按钮按下的处理程序和排序调用的排序函数之间传递选定的排序字段和排序。

所以在 doGet() 中:

// Sort Field and Order
ScriptProperties.setProperties({"sortField": "date","sortOrder": "asc"});

在按钮处理程序中:

function sortHandler(event) {
  var id = event.parameter.source;

  if (id === ScriptProperties.getProperty("sortField")) {
  ScriptProperties.setProperty("sortOrder", (ScriptProperties.getProperty("sortOrder") === "asc")?"desc":"asc");
  } else {
    ScriptProperties.setProperties({"sortField": id, "sortOrder": "asc"});
  }
  var app = UiApp.getActiveApplication();
  app.remove(app.getElementById("ScrollPanel"));
  createForm_(app);
  return app;
}

以及 order 函数本身(这是由数组上的 sort 方法调用的:array.sort(order);在定义网格的代码中):

function orderFunction(a, b) {
  var sortParameter = ScriptProperties.getProperties();
  var asc = sortParameter.sortOrder === "asc";

  switch(sortParameter.sortField) {
    case "date":
      var aDate = new Date(a.date);
      var bDate = new Date(b.date);

      return (asc)?(aDate - bDate):(bDate - aDate);

    case "serviceno":

      return (asc)?(a.serviceno-b.serviceno):(b.serviceno-a.serviceno);

    default: // lexical
      var aLex = String(a[sortParameter.sortField]).toLowerCase();
      var bLex = String(b[sortParameter.sortField]).toLowerCase();

      if (aLex < bLex) {
        return (asc)?-1:1;
      } else if (aLex > bLex) {
        return (asc)?1:-1;
      } else {
        return 0;
      }
  }
}

这种设计的美中不足是谷歌。一旦数组达到一定的大小,排序就会失败,并显示属性服务被过于频繁地调用的错误。该消息建议使用 插入 1s 延迟Utilities.sleep(),但网格已经需要很长时间才能渲染 - 如果数组需要 1s 来决定两个值的顺序,它会如何?

我尝试使用 ScriptDB 重新实现,但是遇到了同样的问题,对 ScriptDB 服务的调用过于频繁,以至于 Google 不喜欢。

那么在没有 orderFunction 访问任何 App Script 服务的情况下,我还能如何实现呢?

4

3 回答 3

1

如果您正在寻找临时存储,我更CacheService喜欢ScriptProperties. 利用

CacheService.getPrivateCache().putCacheService.getPrivateCache().get

于 2013-08-20T06:01:37.337 回答
0

您还可以使用隐藏的小部件doGet在函数之间传递信息handler,它也会比调用 scriptProperties 服务快得多(查看执行记录以了解需要多长时间,您会感到惊讶)

另一方面,如果您真的想继续使用它,您也可以尝试(稍微)减少对 scriptProperties 服务的调用次数,例如在您的sortHandler(event)函数中:

function sortHandler(event) {
  var id = event.parameter.source;
  var sortField = ScriptProperties.getProperty("sortField");
  var sortOrder = ScriptProperties.getProperty("sortOrder");
  if (id === sortField) {
  ScriptProperties.setProperty("sortOrder", (sortOrder === "asc")?"desc":"asc");
  } else {
    ScriptProperties.setProperties({"sortField": id, "sortOrder": "asc"});
  }
  var app = UiApp.getActiveApplication();
  app.remove(app.getElementById("ScrollPanel"));
  createForm_(app);
  return app;
}
于 2013-08-20T06:53:18.387 回答
0

...我还能如何实现呢?

将 HTMLService 与 jQuery DataTable 一起使用,它可以完成您可以想象的所有排序,并且无需编写脚本按钮按下逻辑等即可完成更多操作。这里有一个基本表的电子表格示例http://davethinkingaloud.blogspot.co.nz/2013/03/jsonp-and-google-apps-script.html

于 2013-08-20T23:27:32.480 回答