如何从 Apps 脚本库中调用 CreateMenu()?
How do I call CreateMenu() from within an Apps Script Library?
我正在 Apps 脚本中构建一个库,并希望它能够自我维持。本质上,如果有人想在他们的 Google Sheet 中使用这个库,他们只需要在他们的 Sheets 脚本
中输入以下代码
function onOpen(){
myLib.initialize();
}
这将根据需要设置 sheet。我在这里做的一件事是在 Sheet 本身中实际添加一个菜单项。因此,在我的库代码中,我会有类似的东西;
function initialize(){
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('First item', 'someCallback')
.addToUi();
}
这种做法的问题是,当点击菜单项时,找不到“someCallback”函数。这是有道理的,因为它位于一个单独的库中。它应该像这样使用点符号来调用:myLib.someCallback
有什么方法可以在 运行 时获取库标识符,以便创建创建菜单所需的字符串?
我可以做一些不是我首选的事情,例如:
- 将“myLib”字符串传递给初始化函数
- 直接在
addItem()
函数中输入“myLib”,但我认为这不是很好的做法,如果最终用户更改标识符怎么办从 myLib 到其他东西。
也许有一些运行时方法可以获得库标识符?
答案:
不幸的是,目前无法做到这一点。
更多信息:
我使用 this
关键字和 eval()
函数测试了一些东西,以便动态获取 myLib
的重新定义标识符或调用 someCallback
直接在 initialize
函数中,然而甚至嵌入回调函数 inside initialize
:
funciton initialize() {
var cb = function someCallback() {
// do stuff
};
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('First item', 'cb')
.addToUi();
或:
function initialize() {
function someCallback() {
//do stuff
}
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('First item', 'someCallback')
.addToUi();
}
抛出相同的错误,但未定义 cb
或 someCallback
。
this
的问题:
直接回答你的问题
Maybe there's some Runtime way that I can get the Library Identifier?
答案是肯定的。 有点。
this
关键字非常强大,在运行时您可以使用它来获取用户设置标识符的名称,方法如下:
function onOpen(){
myLib.initialize(this);
}
在myLib.initialize()
中:
function initialize(name) {
console.log(Object.keys(name));
}
控制台显示:['myLib', 'onOpen']
这个问题是,虽然导入库的名称出现在用户脚本中定义的函数列表之前,但如果导入了多个库,您将无法分辨哪个 的键指的是你的库,而它指的是其他的。结果只是调用 name[0]
不会削减它。
正在挖掘:
我进入 Google's Issue Tracker 并发现有一些功能请求与您的用例非常相似:
- AddMenu should be able to use anonymous functions or at least pass parameters
- AddMenu should be able associate an object method to a menu entry, not just a global function
虽然用例不完全相同,但两者的根本问题是匿名函数或参数不能传递给使用UI Apps 脚本的方法。
还有一个相关的功能请求,它要求实现一个包罗万象的样式方法,如果调用了一个不存在的库方法,该方法就会运行一个方法:
要做什么:
通常情况下,我会建议关注问题跟踪器链接并单击星号。但是,在这种情况下,由于您的用例未 完全 在上述功能请求的范围内定义,我建议您使用 this link 来提交 Apps 脚本功能请求并详细说明您在问题中提供的所有信息。
就变通办法而言;同时,您可以做的最好的事情是记录 initialize()
函数需要传递库的标识名称。从任何标准来看,这都不是一个优雅的解决方案,但考虑到 this
的复杂性和尚未实现的功能请求,这可能是最简单的选择。
可能 可以遍历 Object.keys(this)
数组,但我觉得这是一个非常棘手的解决方法,可能会引入不必要的问题(特别是如果,例如,另一个库创建者也恰好有一个名为 someCallback
...)
的函数
参考文献:
我正在 Apps 脚本中构建一个库,并希望它能够自我维持。本质上,如果有人想在他们的 Google Sheet 中使用这个库,他们只需要在他们的 Sheets 脚本
中输入以下代码function onOpen(){
myLib.initialize();
}
这将根据需要设置 sheet。我在这里做的一件事是在 Sheet 本身中实际添加一个菜单项。因此,在我的库代码中,我会有类似的东西;
function initialize(){
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('First item', 'someCallback')
.addToUi();
}
这种做法的问题是,当点击菜单项时,找不到“someCallback”函数。这是有道理的,因为它位于一个单独的库中。它应该像这样使用点符号来调用:myLib.someCallback
有什么方法可以在 运行 时获取库标识符,以便创建创建菜单所需的字符串?
我可以做一些不是我首选的事情,例如:
- 将“myLib”字符串传递给初始化函数
- 直接在
addItem()
函数中输入“myLib”,但我认为这不是很好的做法,如果最终用户更改标识符怎么办从 myLib 到其他东西。
也许有一些运行时方法可以获得库标识符?
答案:
不幸的是,目前无法做到这一点。
更多信息:
我使用 this
关键字和 eval()
函数测试了一些东西,以便动态获取 myLib
的重新定义标识符或调用 someCallback
直接在 initialize
函数中,然而甚至嵌入回调函数 inside initialize
:
funciton initialize() {
var cb = function someCallback() {
// do stuff
};
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('First item', 'cb')
.addToUi();
或:
function initialize() {
function someCallback() {
//do stuff
}
var ui = SpreadsheetApp.getUi();
ui.createMenu('Custom Menu')
.addItem('First item', 'someCallback')
.addToUi();
}
抛出相同的错误,但未定义 cb
或 someCallback
。
this
的问题:
直接回答你的问题
Maybe there's some Runtime way that I can get the Library Identifier?
答案是肯定的。 有点。
this
关键字非常强大,在运行时您可以使用它来获取用户设置标识符的名称,方法如下:
function onOpen(){
myLib.initialize(this);
}
在myLib.initialize()
中:
function initialize(name) {
console.log(Object.keys(name));
}
控制台显示:['myLib', 'onOpen']
这个问题是,虽然导入库的名称出现在用户脚本中定义的函数列表之前,但如果导入了多个库,您将无法分辨哪个 的键指的是你的库,而它指的是其他的。结果只是调用 name[0]
不会削减它。
正在挖掘:
我进入 Google's Issue Tracker 并发现有一些功能请求与您的用例非常相似:
- AddMenu should be able to use anonymous functions or at least pass parameters
- AddMenu should be able associate an object method to a menu entry, not just a global function
虽然用例不完全相同,但两者的根本问题是匿名函数或参数不能传递给使用UI Apps 脚本的方法。
还有一个相关的功能请求,它要求实现一个包罗万象的样式方法,如果调用了一个不存在的库方法,该方法就会运行一个方法:
要做什么:
通常情况下,我会建议关注问题跟踪器链接并单击星号。但是,在这种情况下,由于您的用例未 完全 在上述功能请求的范围内定义,我建议您使用 this link 来提交 Apps 脚本功能请求并详细说明您在问题中提供的所有信息。
就变通办法而言;同时,您可以做的最好的事情是记录 initialize()
函数需要传递库的标识名称。从任何标准来看,这都不是一个优雅的解决方案,但考虑到 this
的复杂性和尚未实现的功能请求,这可能是最简单的选择。
可能 可以遍历 Object.keys(this)
数组,但我觉得这是一个非常棘手的解决方法,可能会引入不必要的问题(特别是如果,例如,另一个库创建者也恰好有一个名为 someCallback
...)