EXTJS 6.7 - class properties not cleared on destroy

Viewed 230

I've created a fiddle just to simulate my problem with class property not being reset on window destroy.
How to test: Open fiddle, press OPEN button, ADD 3 panels, close ext window, press OPEN button again, and add a some more panels.
Panel numbers represent the length of the _panels array property in window.
Now to the problem.
As you can see panel NUMBER when adding new panels is not reset. So if you add 3 panels and close the window, reopen the window panels count shows 3 and then 4 and then 5 instead of 0 1 2 ...
My question is, why?

Fiddle example

Kind regards

Armando

EDIT : so one can see the solution
I ended fixing my application to work like this fiddle. I moved properties to constructor.

constructor: function() {
    Ext.apply(this, {     
        width: 800,      
        height: 600, 
        layout: 'vbox', 
        _panels : []
    }); 
    this.callParent(arguments); 
},
3 Answers

The simple answer for this is prototypal inheritance (see this MDN article). Basically your non-primitives will carry over to new instances because they exist on your prototype class, and because they're non-primitives, it's the same exact reference that's used. To fix this, I would recommend wrapping your _panels variable in the config block, like below, and encourage you to use the appropriate set/get methods, instead of accessing it directly:

config: {
    _panels : []
}

When you define

Ext.define('TestWindow', {
    extend: 'Ext.window.Window',
    _panel: []
});

The TestWindow definition class gets empty array property (no-primitive datatype). When you create an instance by var win = Ext.create('TestWindow'), the instance gets that property. However, when you set:

   onDestroy: function() {
      this._panels = [];
    },

it sets empty array to property _panels of the instance win, not on the definition class TestWindow; TestWindow keeps the existing mutated _panel. And when next time you create new instance, it gets same _panel from class definition.

I understand you did it for demo purpose to show the problem. However, I prefer to let framework do all heavy-lifting (create and destroy etc):

Ext.define('TestWindow', {
    extend: 'Ext.window.Window',

    width: 800,
    height: 600,

    defaultListenerScope: true,
    layout: 'vbox',

    initComponent: function() {
        this._panels = [];
        this.callParent(arguments);
    },

    addPanel: function() {
        console.log(this._panels.length);
        
        var panels = this._panels;
        panels.push(this.add({
            xtype: 'panel',
            title: 'Panel ' + panels.length,
            height: 50,
            width: '100%'
        }));
    },
    
    tbar: [{
        xtype : 'button',
        text: 'add',
        handler: 'addPanel'
    }]

});

A less than correct answer if the prototype behavior in the previous answer is "A feature/intentional bad code/ legacy code with unintended consequences"

Manually overwrite the prototype Value, following instantiation of the panel

manually overwrite _.panels

Related