如何在子类中重写initComponent内Ext.Array.merge的顺序?
解决Ext JS子类重写BasePanel的initComponent时合并顺序不生效的问题
我来帮你捋捋这个问题哈,这其实是Ext JS类继承里很容易踩的一个小坑。你遇到的情况是:子类想改Ext.Array.merge的参数顺序,但要么改了出问题,要么没改的时候直接沿用基类的顺序——核心原因大多是子类没有正确覆盖父类的initComponent逻辑,或者重写时的细节没处理对。
先搞懂问题根源
当你的子类没有显式重写initComponent方法时,Ext JS会直接继承父类(BasePanel)的实现,所以父类里Ext.Array.merge(me.firstFunc(), me.secondFunc(), me.thirdFunc())的顺序肯定会被原样执行。如果重写后出错,大概率是重写的姿势不对,比如漏了调用父类方法,或者逻辑顺序搞反了。
正确的重写姿势
1. 直接重写initComponent(简单直接)
如果你只需要在某个子类里修改合并顺序,直接重写initComponent就行,注意要先处理自己的items逻辑,再调用父类的callParent(和基类的逻辑保持一致):
Ext.define('MyApp.MyPanel', { extend: 'MyApp.BasePanel', initComponent: function () { var me = this; // 这里改成你想要的任意合并顺序,比如把thirdFunc放到最前面 me.items = Ext.Array.merge(me.thirdFunc(), me.secondFunc(), me.firstFunc()); // 必须调用父类的initComponent!否则Panel的基础初始化(渲染、事件等)会失效 me.callParent(arguments); } });
2. 排查重写失败的常见坑
如果按上面写了还是没生效,检查这几个点:
- 子类的
extend路径是不是写错了?比如有没有把MyApp.BasePanel写成Ext.panel.Panel? - 是不是漏了
me.callParent(arguments)?不调用父方法会导致基类的初始化逻辑跑不起来,甚至可能让你的items设置被覆盖。 - 子类有没有重写
firstFunc/secondFunc/thirdFunc?如果这些方法的返回值和你预期不一样,也会让你误以为顺序没生效,先单独测试下这些方法的返回结果。
3. 更优雅的方案:用模板方法模式优化
如果以后有多个子类要改合并顺序,直接重写initComponent会重复代码,不如把合并逻辑拆成一个单独的方法,让子类只重写这个方法:
// 先修改基类BasePanel,把合并逻辑抽成getMergedItems方法 Ext.define('MyApp.BasePanel', { extend: 'Ext.panel.Panel', initComponent: function () { var me = this; // 调用抽出来的方法获取合并后的items me.items = me.getMergedItems(); me.callParent(arguments); }, // 专门负责items合并的模板方法,子类可以轻松重写 getMergedItems: function () { var me = this; return Ext.Array.merge(me.firstFunc(), me.secondFunc(), me.thirdFunc()); }, firstFunc: function () { return []; }, secondFunc: function () { return []; }, thirdFunc: function () { return []; } }); // 子类只需要重写getMergedItems就行,不用动整个initComponent Ext.define('MyApp.MyPanel', { extend: 'MyApp.BasePanel', getMergedItems: function () { var me = this; return Ext.Array.merge(me.thirdFunc(), me.firstFunc(), me.secondFunc()); } });
这种方式更符合开闭原则,以后要改合并逻辑,只需要修改子类的getMergedItems,不会影响基类和其他子类的逻辑。
内容的提问来源于stack exchange,提问作者Nuri Engin
相关产品推荐
相关产品推荐

