我正在编写一个 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 服务的情况下,我还能如何实现呢?