【问题标题】:EXTJS 6.7 - class properties not cleared on destroyEXTJS 6.7 - 销毁时未清除类属性
【发布时间】:2020-09-15 11:07:50
【问题描述】:

我创建了一个小提琴,只是为了模拟我的问题,即在窗口销毁时没有重置类属性。
如何测试: 打开小提琴,按 OPEN 按钮,添加 3 个面板,关闭 ext 窗口,再次按 OPEN 按钮,然后添加更多面板。
面板编号表示窗口中 _panels 数组属性的长度。
现在解决问题。
如您所见,添加新面板时面板 NUMBER 未重置。因此,如果您添加 3 个面板并关闭窗口,请重新打开窗口面板计数显示 3 然后 4 然后 5 而不是 0 1 2 ...
我的问题是,为什么?

Fiddle example

亲切的问候

阿曼多

编辑:这样可以看到解决方案
我结束了将我的应用程序修复为像这样fiddle 工作。我将属性移至构造函数。

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

【问题讨论】:

    标签: extjs extjs6


    【解决方案1】:

    当你定义时

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

    TestWindow 定义类获取空数组属性(非原始数据类型)。当您通过var win = Ext.create('TestWindow') 创建实例时,该实例将获得该属性。但是,当您设置时:

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

    它将空数组设置为实例win的属性_panels,而不是定义类TestWindowTestWindow 保留现有的变异 _panel。当你下次创建新实例时,它会从类定义中获得相同的_panel

    我了解您这样做是为了演示问题。但是,我更喜欢让框架完成所有繁重的工作(创建和销毁等):

    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'
        }]
    
    });
    

    【讨论】:

    • 忘了提到将this._panels = []; 移动到initComponent 中以使其特定于实例。
    • 是的,我同意你的回答我只是在构造函数中做了同样的事情......因为我习惯于在构造函数中初始化类:D
    【解决方案2】:

    对此的简单回答是原型继承(参见this MDN 文章)。基本上,您的非基元将延续到新实例,因为它们存在于您的原型类中,并且因为它们是非基元,所以使用的引用完全相同。要解决此问题,我建议您将 _panels 变量包装在 config 块中,如下所示,并鼓励您使用适当的 set/get 方法,而不是直接访问它:

    config: {
        _panels : []
    }
    

    【讨论】:

    • 我将它们移至构造函数,因为我想让这些属性“私有”
    • 您仍然可以使用配置方法,但如果有问题,请将其标记为 private 并附上评论,但您所做的是另一种完全可以接受的方法。
    • 你可以使用 onDestroy: function() { this._panels.length = 0 },。它将清空数组。
    • @Ovais - 你不想这样做,因为 _panels 引用正在与该类的其他实例共享(因为,正如 incutonez 所说,它来自原型)。正确的解决方案是使其被共享。
    • 我已经结束了对我的应用程序的修复,使其像 fiddle 这样工作。我将属性移动到构造函数。 ` 构造函数:function() { Ext.apply(this, { width: 800, height: 600, layout: 'vbox', _panels : [], }); this.callParent(参数); },`
    【解决方案3】:

    如果上一个答案中的原型行为是“具有意外后果的功能/故意错误代码/遗留代码”,则不正确答案

    在面板实例化之后手动覆盖原型值

    【讨论】:

    • 请注意,“少于正确答案”引用了先前答案中的要点。如果您在旧系统中,以前存在不良行为,那么纠正可能会有问题。同时接受上一个答案,因为它回答了问题。
    猜你喜欢
    • 1970-01-01
    • 2011-02-23
    • 2019-01-19
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    相关资源
    最近更新 更多