ExtJS Modern扩展组件时可替代initComponent的初始化函数是什么
ExtJS Modern版本initComponent替代方案及重复渲染问题处理
问题背景
在ExtJS 6.2 classic版本中扩展组件时,通常会实现initComponent方法编写初始化逻辑。但ExtJS Modern版本的Ext.Container没有initComponent方法,除constructor外,Modern版本有什么方法可以替代initComponent的作用?
实际开发中遇到故障:将组件初始化逻辑写在constructor中,再次展示组件时constructor会重复执行,且入参config为之前更新过的配置,导致本该只渲染一次的内容被多次渲染。
故障相关代码
Ext.define('AppName.view.settings.CalloutBox', { extend: 'Ext.Container', xtype: 'calloutbox', layout : { type : 'hbox', }, constructor: function(config) { // 这段逻辑用于临时规避重复渲染故障 if (config.cls) { this.callParent(arguments); return; } config.cls = `myclass`; // 此处编程方式添加元素会引发故障:构造函数下次执行时元素会被再次添加 config.items = [{ xtype : 'container', cls : `alert__icon-box`, layout: { type : 'vbox', pack : 'center', align : 'middle' }, items: [{ xtype :'label', cls : `alert__icon`, html : `<i class="x-font-icon md-icon-alert"></i>`, }] }]; this.callParent(arguments); } });
核心问题解答
ExtJS Modern版本中,initialize方法就是initComponent的官方等价替代方案。该方法会在组件所有配置应用完成后、渲染前执行,且整个组件生命周期仅执行一次,完全可以替代constructor存放组件初始化、固定子项添加、初始事件绑定这类逻辑,不会出现非预期重复执行的问题。
用initialize改造后的组件示例
Ext.define('AppName.view.settings.CalloutBox', { extend: 'Ext.Container', xtype: 'calloutbox', layout : { type : 'hbox', }, cls: 'myclass', // 固定配置可以直接定义在类属性上,不需要写在初始化逻辑里 initialize: function() { this.callParent(arguments); // 仅执行一次的初始化逻辑写在这里 this.add([{ xtype : 'container', cls : `alert__icon-box`, layout: { type : 'vbox', pack : 'center', align : 'middle' }, items: [{ xtype :'label', cls : `alert__icon`, html : `<i class="x-font-icon md-icon-alert"></i>`, }] }]); } });
重复渲染故障修复
故障根因
元素重复渲染的根本原因是上层调用逻辑每次都重新创建CalloutBox所在的modal,而非直接复用已有的组件实例。就算用initialize方法,每次新建组件实例时也会执行初始化逻辑,属于正常行为。
原错误调用代码
Ext.Viewport.add({ xtype: 'mymodal' }).show();
修复后调用代码
const mymodal = Ext.getCmp('mymodal'); // 若DOM中已存在该组件,直接展示即可 if (mymodal) { mymodal.show(); return; } // 否则创建并展示组件 Ext.Viewport.add({ xtype: 'mymodal', id: 'mymodal' }).show();
注:给modal设置固定id是
Ext.getCmp能找到已有实例的前提,需要提前给modal组件配置固定id。
内容的提问来源于stack exchange,提问作者user5507535
相关产品推荐
相关产品推荐

