大約三個星期前我開始調查GAS,在搜索SO時發現很多事情與其他語言相比並不容易。
難以理解的事情之一是找出事件處理程序中eventInfo中存在哪些參數。我沒有找到一篇文章如何獲取控件的名稱。但我知道這應該是可能的,因爲JSON.stringify(e)
確實寫入參數的名稱。
在檢查樹時,我需要對treeItems的引用,所以我想出瞭如何獲取在事件處理程序中添加的控件的名稱。
我在樹上執行UI操作時使用onMouseUpHandler,但也可以使用其他處理程序。
函數validateParameter允許找出參數是否引用控件。 在我的應用程序中,我創建了包含複選框的treeItems,以允許識別我想顯示的文件夾。 爲了識別控件,我使用了folderId和一個包含下劃線的前綴,以便區分我添加的控件和eventInfo的其他參數。因爲我的目標是在需要的時候填充樹的某些部分(所以:在用戶點擊樹形目錄旁邊的擴展分支按鈕之後),我只是在創建時添加了「級別」指示符樹。當然這個功能可以刪除。
var chkPrefix = "chk_"; // Prefix for names and ids of checkboxes on treeitems
var triPrefix = "tri_"; // Prefix for names and ids for treeitems
var useCheckBox = true; // Test using checkboxes --> change accordingly
// false = Do not use checkboxes on treeitems
// true = Use checkboxes on treeitems
// Create various handlers
var onSelectHandler = app.createServerHandler("onSelectHandler");
var onMouseUpHandler = app.createServerHandler("onMouseUpHandler");
var onCheckBoxHandler = app.createServerHandler("onCheckBoxHandler");
// Create a tree of folders starting from 'My Drive' --> to the folder you want
var tree = app.createTree().setAnimationEnabled(true);
var rootTree = DriveApp.getRootFolder(); // Root of the drive --> change to the folder you want
var level = 3; // Allowed maximum depth of the tree (0 = ALL) --> avoiding excessive runtime --> building treeitems when needed
var rootItem = populateFolderTree_(rootTree, tree, level); //
function populateFolderTree_(folder, parentItem, level)
{ // Internal function
var itemName = folder.getName();
var itemId = folder.getId();
if (useCheckBox === false)
{ // Just sho the name of the folder
var treeItem = app.createTreeItem(itemName);
}
else
{ // Create a checkbox on every treeitem
var chkBox = app.createCheckBox(itemName)
.setId(chkPrefix + itemId).setName(chkPrefix + itemId);
chkBox.addClickHandler(onCheckBoxHandler); // Add a handler
var treeItem = app.createTreeItem(chkBox);
}
treeItem.setId(triPrefix + itemId);
parentItem.addItem(treeItem);
if ((level === 0) || (level > 1))
{ // Maximum depth of the tree has not been reached (yet)
var subLevel = level - 1;
var subFolders = folder.getFolders();
while (subFolders.hasNext())
{ // Recursively add subfolders
var subFolder = subFolders.next();
populateFolderTree_(subFolder, treeItem, subLevel);
}
}
return treeItem; // Will eventually return the root of the tree
}
即使代碼是不完整的,我相信兩個部分(生成文件夾樹部分,檢索的evenInfo參數的名稱)可以爲別人有用。
function onMouseUpHandler(e)
{
var app = UiApp.getActiveApplication();
var source = e.parameter.source; // Contains the Id of the tree
var widget = app.getElementById(source);
Logger.log('\nOnMouseUpHandler ' + source + ' widget=' + widget.getId() + ' = ' + widget.getType());
var eventParameters = extractParameters(e, validateParameter);
var numParams = eventParameters.length
if (numParams > 0)
{
var keys = eventParameters.keys();
var values = eventParameters.values();
for (var i=0; i<numParams; i++)
{
Logger.log('key[' + i + '] = ' + keys[i] + ' value = ' + values[i]);
};
};
return app;
}
function validateParameter(namePar, valuePar)
{ // Skip all parameters not referring to treeitems
var accept = false;
var xx = namePar.substr(0, chkPrefix.length);
if (chkPrefix === namePar.substr(0, chkPrefix.length))
{
accept = true;
}
else if (triPrefix === namePar.substr(0, triPrefix.length))
{
accept = true;
};
Logger.log('namePar=' + namePar + ' accept=' + accept + ' xx=' + xx);
return accept;
}
function extractParameters(e, validateFunction)
{
var text = JSON.stringify(e);
start = text.indexOf(':{') + 1;
letters = text.indexOf('}') - start;
Logger.log('text=' + text);
var arrParameters = text.replace('"','').substr(start, letters).split(",");
var skipValidation = ((validateFunction === null) || (validateFunction === undefined));
// Store parameters in a hashtable
var statusControls = new HashTable(); // Any hashtable will do
var numParameters = arrParameters.length;
for (var i=0; i<numParameters; i++)
{
var parameter = arrParameters[i];
var pos = parameter.indexOf(":");
var nameVar = parameter.substr(1, pos - 2);
var valueVar = parameter.substr(pos + 2, parameter.length - pos - 3);
var accept = true;
if (skipValidation === false) accept = validateFunction(nameVar, valueVar);
if (accept === true) statusControls.addItem(nameVar, valueVar); // Only store acceptable parameters
}
return statusControls;
}
正如我使用JSON。然後再對其輸出進行解碼,這種獲得控制的方法肯定會得到改進。但就像我之前寫的那樣:我沒有找到如何做到這一點,所以我自己做了。
我想創建一個從樹派生類(也許從TreeItem爲好)做的事情是在其他語言中常見的(即檢索ITEMCOUNT()在任何層次,走在兩個方向上的樹;檢索狀態在任何時候對treeItems的複選框等),因爲那是當時真的缺失(至少在我看來),使其很難發展。
顯然,在GAS(和Javascript)僅僅3周後,我不能期望知道很多東西。由於這裏有很多人有我缺少的知識,我希望他們能通過改進代碼並告訴我如何實現。
最後一條評論: 我發現BetterLog
確實使開發比標準Logger更容易。看看https://sites.google.com/site/scriptsexamples/custom-methods/betterlog#TOC-Documentation-Support-Resources