我正在为学校构建一个容器绑定的谷歌应用程序脚本。学校要求每个书面项目都有“学校标题”。学校使用A-G区块作为期间。我的目标是将有一个菜单“学校标题”,当打开时它有子菜单“A Block”,“B Block”,“C Block”,并且在每个子菜单中每个类别都有一个选项,将该类的标题插入文档的标题
这是我的代码:
var BLOCKS = "abcdefg";
var CLASSES = ["English", "History", "Science", "Writing", "Latin", "Math", "Study Skills"];
var FUNCTION_NAMES;
var global = {};
init();
/**
* The onOpen function runs automatically when the Google Docs document is
* opened. Use it to add custom menus to Google Docs that allow the user to run
* custom scripts. For more information, please consult the following two
* resources.
*
* Extending Google Docs developer guide:
* https://developers.google.com/apps-script/guides/docs
*
* Document service reference documentation:
* https://developers.google.com/apps-script/reference/document/
*/
function onOpen() {
init();
// Add a menu with some items, some separators, and a sub-menu.
var menu = DocumentApp.getUi().createMenu('School Heading')
for(var i = 0; i < BLOCKS.length; i++){
block = BLOCKS[i];
Logger.log("Block: " + block)
menu = menu.addSubMenu(DocumentApp.getUi().createMenu(block + " Block")
.addItem('English', 'eng' + block)
.addItem('History', 'his' + block)
.addItem('Science', 'sci' + block)
.addItem('Writing', 'wri' + block)
.addItem('Latin', 'lat' + block)
.addItem('Math', 'mat' + block)
.addItem('Study Skills', 'stu' + block));
defineFunctions(block, this);
}
menu.addToUi();
}
function getFunc(class,block){
return function(){
createHeading(class,block);
}
}
function defineFunctions(block, global){
Logger.log(FUNCTION_NAMES)
for(var i = 0; i < FUNCTION_NAMES.length; i++){
var funcName = FUNCTION_NAMES[i] + block;
eval("function " + funcName + " () { createHeading('"+ CLASSES[i] + "', '" + block + "'); }");
}
}
function createHeading(class, block){
var header = DocumentApp.getActiveDocument().getHeader();
if(!header){
header = DocumentApp.getActiveDocument().addHeader();
}
header.insertParagraph(0, "Name\n{class}, Block {block}".replace("{class}", class).replace("{block}", block)).setAlignment(DocumentApp.HorizontalAlignment.RIGHT);
}
function init(){
if(!Array.isArray(BLOCKS)){
BLOCKS = BLOCKS.toUpperCase().split("");
}
if(!Array.isArray(CLASSES)){
CLASSES = CLASSES.split("\n");
}
if(!Array.isArray(FUNCTION_NAMES) || FUNCTION_NAMES.length !== CLASSES.length){
FUNCTION_NAMES = [];
for(var i = 0; i < CLASSES.length; i++){
FUNCTION_NAMES.push(CLASSES[i].toLowerCase().substring(0,3));
}
}
}
当我选择学校标题&gt;块&gt;英语我得到'脚本功能未找到engA'
我的问题是,为什么eval不起作用,我是否可以将匿名函数传递给Menu.addItem?
答案 0 :(得分:4)
我相信eval可能正常工作,但不能保证它与调用菜单时执行的脚本实例相同。在您准备好调用菜单之前,Google Apps脚本无法将所有这些功能保留在内存中,所以到那时,您将拥有一个干净的平板,并且不再引用所有这些功能。
在此阶段无法传递匿名函数/参数,它被归类为增强:https://code.google.com/p/google-apps-script-issues/issues/detail?id=477虽然没有太多进展。
为什么不使用侧栏代替菜单,在那里你可以创建一个带有选择器的UI,根据该UI可以插入正确的标题。一旦你有了这种机制,就可以使用侧栏来获得其他很酷的东西。
答案 1 :(得分:3)
您的eval()
定义了函数中for
循环内的函数,因此作用域规则意味着它们在该范围之外不可用。通过将该代码移到所有其他函数之外,eval()
'd函数将可用于每个正在运行的脚本实例。
这有效:
var BLOCKS = "abcdefg";
var CLASSES = ["English", "History", "Science", "Writing", "Latin", "Math", "Study Skills"];
var FUNCTION_NAMES;
var global = {};
init();
/// Moved
for(var _i = 0; _i < BLOCKS.length; _i++){
var _block = BLOCKS[_i];
for(var _j = 0; _j < FUNCTION_NAMES.length; _j++){
var _funcName = FUNCTION_NAMES[_j] + _block;
eval("function " + _funcName + " () { createHeading('"+ CLASSES[_j] + "', '" + _block + "'); }");
}
}
///
debugger; // Pause in debugger (All the functions are there!)
/**
* The onOpen function runs automatically when the Google Docs document is
* opened. Use it to add custom menus to Google Docs that allow the user to run
* custom scripts. For more information, please consult the following two
* resources.
*
* Extending Google Docs developer guide:
* https://developers.google.com/apps-script/guides/docs
*
* Document service reference documentation:
* https://developers.google.com/apps-script/reference/document/
*/
function onOpen() {
// Add a menu with some items, some separators, and a sub-menu.
var menu = DocumentApp.getUi().createMenu('School Heading')
for(var i = 0; i < BLOCKS.length; i++){
block = BLOCKS[i];
Logger.log("Block: " + block)
menu = menu.addSubMenu(DocumentApp.getUi().createMenu(block + " Block")
.addItem('English', 'eng' + block)
.addItem('History', 'his' + block)
.addItem('Science', 'sci' + block)
.addItem('Writing', 'wri' + block)
.addItem('Latin', 'lat' + block)
.addItem('Math', 'mat' + block)
.addItem('Study Skills', 'stu' + block));
//defineFunctions(block, this);
}
menu.addToUi();
}
function getFunc(class,block){
return function(){
createHeading(class,block);
}
}
function defineFunctions(block, global){
Logger.log(FUNCTION_NAMES)
for(var i = 0; i < FUNCTION_NAMES.length; i++){
var funcName = FUNCTION_NAMES[i] + block;
eval("this[" + funcName + "] = function () { createHeading('"+ CLASSES[i] + "', '" + block + "'); }");
}
debugger;
}
function createHeading(class, block){
var header = DocumentApp.getActiveDocument().getHeader();
if(!header){
header = DocumentApp.getActiveDocument().addHeader();
}
header.insertParagraph(0, "Name\n{class}, Block {block}".replace("{class}", class).replace("{block}", block)).setAlignment(DocumentApp.HorizontalAlignment.RIGHT);
}
function init(){
if(!Array.isArray(BLOCKS)){
BLOCKS = BLOCKS.toUpperCase().split("");
}
if(!Array.isArray(CLASSES)){
CLASSES = CLASSES.split("\n");
}
if(!Array.isArray(FUNCTION_NAMES) || FUNCTION_NAMES.length !== CLASSES.length){
FUNCTION_NAMES = [];
for(var i = 0; i < CLASSES.length; i++){
FUNCTION_NAMES.push(CLASSES[i].toLowerCase().substring(0,3));
}
}
}