Search code examples
javascriptextjsevent-handlingdom-eventsextjs6

ExtJs 6.0 - Javascript event handler function scope inside Ext.application


I do not understand how I can make the event handler function named some_function() get called:

var some_app = Ext.application({
  name   : 'some_app_name',
  launch : function() {
      function some_function(){
          Ext.toast('some_function called!');
      };
      var some_panel = Ext.create('Ext.panel.Panel', {
          html:"Some <span onmouseover='some_function()'>text</span> with "+
               "a html-span that should"+
               " listen to mouseover events"
      });
      var some_viewport = new Ext.Viewport({
          items: [some_panel],
          renderTo : Ext.getBody()
      });
  }
});

Here is the corresponding Sencha Fiddle: https://fiddle.sencha.com/#fiddle/135r

So the question is basically: What do I have to do in order to call some_function()?


Note:

When I execute the Fiddle in my browser I can see that it gives me this error in the Browser-console:

Uncaught ReferenceError: span_onmouseover_event_handler is not defined.


Solution

  • Inline event handlers are executed in the global scope. The "function is not defined" error is self-explanatory - your handler exists only in the local scope of application launch function. There isn't a nice way to bind context to an inline declaration but if you insist on this style you can at least avoid polluting the global scope by declaring the handler as a member variable of the application:

    var some_app = Ext.application({
        name: 'some_app_name',
        some_function: function(){
            Ext.toast('some_function called!');
        },
        // ...
    });
    

    Then it can be reference with it's fully qualified path like so:

    <span onmouseover="some_app_name.app.some_function()">
    

    » fiddle


    That said, it would be much cleaner if you gave your markup a class attribute and let handle the event delegation as in general this will avoid potential code duplication and issues with scope. For example you could declare your panel like this:

    var some_panel = Ext.create('Ext.panel.Panel', {
        html: "Some <span class='some_class'>text</span> with "+
              "a html-span that should"+
              " listen to mouseover events",
        listeners: {
            element: 'el',
            delegate: 'span.some_class',
            mouseover: some_function
        }
    });
    

    » fiddle