Google Apps 脚本 (V8);为什么我不能在 onOpen 中使用对象实例? [英] Google Apps Script (V8); why can't I use an object instance inside of onOpen?

查看:36
本文介绍了Google Apps 脚本 (V8);为什么我不能在 onOpen 中使用对象实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么我不能在 onOpen 内部使用对象实例?

Why can't I use an object instance inside of onOpen?

我正在试验使用新的 V8 运行时的 Google Apps 脚本.我编写了一些简单的代码,它在 onOpen 函数中创建了一个类的实例,并在我单击菜单项时尝试将调用关联到该实例上的方法.

I'm experimenting with Google Apps Script using the new V8 runtime. I wrote some simple code which makes an instance of a class in the onOpen function and tries to associate a call to a method on that instance when I click on a menu entry.

当我单击关联的菜单项时,出现找不到脚本函数"错误.但是,当我创建类的全局实例或在另一个函数中创建本地实例时,它工作正常.

When I click the associated menu entry, I get a "Script function not found" error. However, when I either create a global instance of the class or create a local instance in another function it works fine.

我尝试记录本地实例或全局实例的值,但它只显示一个空对象:{}.

I tried logging the value of either a local instance or a global instance, but it only shows an empty object: {}.

这是一个错误,还是我在阅读文档时遗漏了一些细节?

Is this a bug, or some detail I missed while reading the documentation?

/** Application Class */
class Application {
    /**
     * ShowUi
     */
    showUi() {
        // const html = HtmlService.createHtmlOutputFromFile('Ui');
        const html = HtmlService.createHtmlOutput('<h1>Hello World</h1>');
        const ui = SpreadsheetApp.getUi();
        ui.showModalDialog(html, 'User Interface');
    }
}

const global_app = new Application();

/** onOpen */
function onOpen() {
    const app = new Application();
    const ui = SpreadsheetApp.getUi();
    const menu = ui.createMenu('JSClass Example');

    console.log('app, local scope:');
    console.log(app);

    console.log('app, global scope');
    console.log(global_app);

    menu.addItem('Show UI (local)', 'app.showUi');
    menu.addItem('Show UI (global)', 'global_app.showUi');
    menu.addItem('Show UI (global fn)', 'showUi');

    menu.addToUi();
}

/** showUi */
function showUi() {
    const app3 = new Application();
    app3.showUi();
}

此代码的绑定电子表格位于此处.不过,我认为您必须制作一份副本并点击一些看起来很吓人的警告才能真正运行它.

My bound Spreadsheet for this code is here. I think you'll have to make a copy and click through some scary-looking warnings to actually run it, though.

推荐答案

在您的示例中,onOpen() 方法仅用于填充菜单,但不是在菜单选项时执行被选中.

In your example, the onOpen() method is executed solely to populate the menu, but not when a menu option is selected.

当您选择一个菜单项时,它会在新的执行上下文中执行,并且不会继承上次执行(即填充菜单)的 onOpen() 函数内的状态.

When you select a menu item, it's performed in a fresh execution context and the state from within the onOpen() function from the previous execution (i.e. to populate the menu) is not carried over.

另一种方法是使用静态方法,您可以调用它而无需创建类的实例.

Another approach is using a static method, which you can call without having to create an instance of the class.

class Application {
    static showUi() {
        const html = HtmlService.createHtmlOutput('<h1>Hello World</h1>');
        const ui = SpreadsheetApp.getUi();
        ui.showModalDialog(html, 'User Interface');
    }
}

function onOpen() {
    const app = new Application();
    const ui = SpreadsheetApp.getUi();
    const menu = ui.createMenu('V8 Menu Test');
    menu.addItem('Show UI', 'Application.showUi');
    menu.addToUi();
}

这篇关于Google Apps 脚本 (V8);为什么我不能在 onOpen 中使用对象实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆