简体   繁体   中英

Cannot call static method from html

I have a class with a static method that I am trying to call from my html page. When I try to call the method using Class.Method() syntax I get an eror: "<Class name > is not defined". When I call that same static method from instances of other javascript classes the static methods work fine.

I managed to kludge a workaround together but it does not look right:

window.dlg = Dialogs;       // static methods only // do I have to do this?

This question appears to validate my belief that I should be able to call my method using Class.Method() syntax.

This question appears to address the issue but does not explain how a static method might be called from html.

What am I doing wrong?

// main.js

import { Site } from './site.js';
import { Dialogs } from './dialogs.js';

(async function ($) {
    "use strict";
    window.site = new Site();   // instance methods

    // hack:
    window.dlg = Dialogs;       // static methods only // do I have to do this?
    await window.site.Init();
})(jQuery);

// dialogs.js

class Dialogs {
    static ShowLoginDialog() {
        $('#login-dialog').modal('show');
    }
}
export { Dialogs };

// html

// works            
<a href="#" onclick="window.dlg.ShowLoginDialog()"><i class="icofont-login"/>&nbsp;Log in</a>

// does not work but I think it should. Error msg:  Dialogs is not defined.
<a href="#" onclick="Dialogs.ShowLoginDialog()"><i class="icofont-login"/>&nbsp;Log in</a>

Avoid inline handlers , they have way too many problems to be worth using in a modern codebase. Since you're using modules, the Dialogs won't be available globally unless you explicitly assign it to the global object which, as you've noticed, is an ugly hack (and inline handlers can only reference global variables). You should attach the event listener properly using Javascript instead: select the element inside your script, and call addEventListener on it:

// main.js

import { Site } from './site.js';
import { Dialogs } from './dialogs.js';

(async function ($) {
    "use strict";
    window.site = new Site();   // instance methods

    document.querySelector('a.login-anchor').addEventListener('click', () => {
        Dialogs.ShowLoginDialog()
    });
    await window.site.Init();
})(jQuery);

where a.login-anchor can be replaced with whatever selector you want to target the <a> with the listener:

<a href="#" class="login-anchor"><i class="icofont-login"/>&nbsp;Log in</a>

You also don't need to put site onto the global object either - put into a variable scoped just to the module instead:

const site = new Site();
await site.init();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM