Results 1 to 7 of 7

Thread: [DUPE-452][3.x] Ext.menu.Menu hide event fires after the destroy event

    Thank you for reporting this bug. We will make it our priority to review this report.
  1. #1
    Ext JS Premium Member
    Join Date
    Mar 2009
    Posts
    96
    Vote Rating
    0
      0  

    Default [DUPE-452][3.x] Ext.menu.Menu hide event fires after the destroy event

    The code i used for the test:
    Code:
    Ext.onReady(function(){
        Ext.getDoc().on({
            'contextmenu':{
                scope:this,
                fn:function(e){
                    e.preventDefault();
                    if(!this.testMenu){
                        this.testMenu = new Ext.menu.Menu({
                            items:[
                                {
                                    text:'destroy menu',
                                    scope:this,
                                    handler:function(){
                                        this.testMenu.destroy();
                                    }
                                }
                            ]
                        });
                        Ext.util.Observable.capture(this.testMenu,function(eventName){
                            console.log('menu fire: ' + eventName);
                        });
                        this.testMenu.showAt(e.getXY());
                    }
                }
            }
        });                
    });
    The problem: Throws the following JS error :

    Code:
    me.dom is undefined
    .../script/lib/ext/ext-all-debug.js
    Line 3844

    The cause: The menu beforehide / hide set of events fires after the beforedestroy/destroy set of events as shown by the console output posted below
    ...
    menu fire: mouseout
    menu fire: mouseover
    menu fire: beforedestroy
    menu fire: destroy
    menu fire: itemclick
    menu fire: click
    menu fire: beforehide
    Suggested resolution: hide the menu before the handler is executed. As i'm not using any special menu items, this workaround seems to mask the problem.

    The above case is the most obvious one, however, the same error appears when clicking a menu item triggers the destruction of a component that it is bound to.

    Thank you!

  2. #2
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    119
      0  

    Default

    Destroying components from within handlers is usually a bad idea, because the code that follows the handler call could still rely on the component being present.

    I would recommend using:
    Code:
    this.testMenu.destroy.defer(1, this.testMenu);
    This way the click can be fully handled before the destroy is executed.

  3. #3
    Ext JS Premium Member
    Join Date
    Mar 2009
    Posts
    96
    Vote Rating
    0
      0  

    Default

    Shouldn't this be fixed? Or at least made 'dumb' proof so that it checks the objects before calling methods on them?

    This is the most basic isolation i found for this problem, initially it popped out in situations quite different from this one.

    In my case the menu is bound to a grid as a context menu. The grid itself is part of a tabpanel with closable tabs. The same error appears if i:
    - right click on a grid row (row context menu pops up)
    - close the tab that contains the grid while the context menu is still displayed

    Is this a bug or just expected behaviour? I'm asking because that event chain just doesn't look right....i mean i'm ok with the itemClick and handler priority but the component tries to hide itself after it has been destroyed...

  4. #4
    Sencha User Jamie Avins's Avatar
    Join Date
    Mar 2007
    Location
    Redwood City, California
    Posts
    3,661
    Vote Rating
    19
      0  

    Default

    We will look at it for 3.2.

  5. #5
    Sencha User
    Join Date
    Nov 2009
    Location
    France
    Posts
    23
    Vote Rating
    0
      0  

    Cool simple hotfix, why not using proposed ones

    Hi,

    1. Draduc suggested hotfix : Suggested resolution: hide the menu before the handler is executed
    First i found this solution, but when your menu has to stay open, u don't have to decide to hide it. Simple to write for a simple example, but difficult for complex usages.

    2. Condor suggested hotfix :
    Code:
    this.testMenu.destroy.defer(1, this.testMenu))
    can be applied in this (simple) testcase, but when you have params that can add menus, and some superclasses, and more, u don't know if you have a menu, floating menus,... And put a defer EVERYWHERE is not the solution for me

    I don't agree for these 2 previous solutions, because it's the framework role to manage this case for u !

    some pretty solutions for me :

    1. @ end of Component.destroy, put
    Code:
    this.rendered = false;
    So, when some event tells to hide, it first test rendered, and so do not hide (it's okay, because it's destroyed)

    Code:
    Ext.Component.override({
        destroy : function(){
            if(!this.isDestroyed){
                if(this.fireEvent('beforedestroy', this) !== false){
                    this.destroying = true;
                    this.beforeDestroy();
                    if(this.ownerCt && this.ownerCt.remove){
                        this.ownerCt.remove(this, false);
                    }
                    if(this.rendered){
                        this.el.remove();
                        if(this.actionMode == 'container' || this.removeMode == 'container'){
                            this.container.remove();
                        }
                    }
                    this.onDestroy();
                    Ext.ComponentMgr.unregister(this);
                    this.fireEvent('destroy', this);
                    this.purgeListeners();
                    this.destroying = false;
                    this.isDestroyed = true;
                    this.rendered = false; // ADDED LINE
                }
            }
        }
    });
    2. in some events, check that element is not destroyed :
    Code:
    if (!this.isDestroyed)
    I prefer the Solution 2, pretty for me, but in my project i set the Solution 1, more easy to write (Solution 2 requires to know all events/methods that want to do some work on el


    Bye

    Pyja

  6. #6
    Sencha User Jamie Avins's Avatar
    Join Date
    Mar 2007
    Location
    Redwood City, California
    Posts
    3,661
    Vote Rating
    19
      0  

    Default

    The speciic issue is a dupe of Bug #438. Solution 2 is actually what was taken there. There's a race condition for the onWindowResize event we cannot stop (without a buffer). An additional isDestroyed check has been added and resolves the issue.

  7. #7
    Sencha Premium Member
    Join Date
    Mar 2015
    Location
    Raleigh, NC
    Posts
    41
    Vote Rating
    2
      0  

    Default

    In EXTJS 6.2 I'm getting this: Ext.util.Event.fire(): Attempting to fire "hide" event on destroyed Ext.menu.Menu instance with id: menu-xxxx

    Guessing maybe this is related and resurfaced?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •