1. #1
    Sencha User
    Join Date
    Aug 2011
    Location
    Germany
    Posts
    4
    Vote Rating
    0
    Sahako is on a distinguished road

      0  

    Default Destroying List results in plugin zombie objects

    Destroying List results in plugin zombie objects


    Greetings,

    I've run into a problem when I want to destroy a list that's using a listpaging / pullrefresh plugin.
    What happens is that, basically, the plugin objects remain even though the list is destroyed. When a new instance of the list is created and a pull refresh triggers, the old plugin instances fire their listeners and, since their list references are invalid, throw all sorts of errors.

    I have tried to remove the listeners defined for the plugins manually before the list is destroyed, they still fire though. Removing all the references to the list inside the plugin didn't help either.

    So my question is, how do you correctly destroy a plugin that is bound to a list?


    Detailed explanation and code examples

    The basic layout of the app is as follows:
    There's one tabbed Viewport that contains two panels, each of them containing a title toolbar as docked item, another toolbar and one list as normal items. To reduce memory consumption, the panel that's currently not visible should have its items (toolbar, list) destroyed. Once the user switches panels, the now visible panel re-creates the items.

    The list component
    Code:
    app.def.ListComponent = Ext.extend(Ext.List, {    scroll: false,
        loadingText: '',
        itemCls: 'document-list-item',
        itemTpl: tplDocumentListItem,
        plugins: [app.def.ListPluginRefresh, app.def.ListPluginPaging],
    
    
        listeners: {
            beforedestroy: function() {
                console.log('LC::destroy');
                if (this.plugins) {
                    if (Ext.isArray(this.plugins)) {
                        for (var i = 0; i < this.plugins.length; i++) {
                            this.plugins[i].unload();
                        }
                    } else {
                        this.plugins.unload();
                    }
                    this.plugins = null;
                }
            }
        },
    
    
        initComponent: function() {
    
    
            // Initialize list according to type
            switch(this.listtype) {
                case 'document':
                    this.store = app.stores.documents;
                    this.emptyText = '<div class="list-empty-default">'+EMPTY_LIST_DEFAULT+'</div>';
                    break;
    
    
                case 'event':
                    this.store = app.stores.events;
                    this.grouped = true;
                    this.emptyText = '<div class="list-empty-event">'+EMPTY_LIST_EVENT+'</div>';
                    break;
            }
    
    
            app.def.ListComponent.superclass.initComponent.apply(this, arguments);
        }
    });
    Overrides for the plugins
    Code:
    Ext.override(Ext.plugins.ListPagingPlugin, {
             unload: function() {
            //this.el.remove();
            //this.list = null;
            this.clearListeners();
        }
    });
    
    
    Ext.override(Ext.plugins.PullRefreshPlugin, {
        unload: function() {
            //this.el.remove();
            //this.list = null;
            this.clearListeners();
        }
    });
    Each panel implements the following functions that handle creation and destruction of the items
    Code:
    contentInit: function() {
        // Called by the "activate" listener of the panel
        this.add(app.def.LocationToolbar);
        this.add(new app.def.ListComponent({listtype: 'document'}));
    
        if (!this.loadMask) {
            this.loadMask = new Ext.LoadMask(this.el.child('.x-panel-body'), {msg: WAIT_MESSAGE, store: app.stores.documents});
        }
    
        this.doLayout();
        this.contentInitialized = true;
    
        if (!this.dataInitialized) {
            app.stores.documents.load(Ext.emptyFn);
            this.dataInitialized = true;
        }
    },
    
    contentPurge: function() {
        // Called by the "cardswitch" listener of the viewport
        this.removeAll(true);
        this.contentInitialized = false;
    },
    Last edited by Sahako; 5 Aug 2011 at 4:58 AM. Reason: typos