I should know better, but recently I extended Ext.Panel and defined the plugins array as part of the object literal.
MyKlass = Ext.extend(Ext.Panel, { plugins:['cool', 'cooler'], initComponent:function() { MyKlass.superclass.initComponent.apply(this, arguments); } });
That’s all well and good, except there’s an important consequence to the above. As mentioned in the documentation, in reference to the second argument to Ext.extend for the two parameter signature: A literal with members which are copied into the subclass’s prototype, and are therefore shared between all instances of the new class
.
In short, it means every instance of MyKlass shares a reference to the plugins array, not its own copy. That can be a problem if you need to add or remove a plugin in instances or subclasses.
If you enjoy the above pattern, you can clone the array so a pristine copy is being modified. Below I use the Ext.ux.clone extension when extending my class above. The plugins array is still shared amongst all classes and subclasses, though.
newKlass = Ext.extend(MyKlass, { addPlugin:false, initComponent:function() { if(this.addPlugin) { this.plugins = Ext.ux.clone(this.plugins||[]).concat('new-plugin'); } MyKlass.superclass.initComponent.apply(this, arguments); } });
Another approach is to define the array in the constructor or within initComponent itself.
MyKlass = Ext.extend(Ext.Panel, { constructor:function(config) { // Each instance gets its own copy now -- the prototype does not have plugins applied to it if(this.plugins) { this.plugins = this.plugins.concat('cool', 'cooler'); } else { Ext.apply(this, {plugins:['cool', 'cooler']}); } MyKlass.superclass.constructor.call(this, config); } });
Strings, Numbers, and Booleans aren’t a worry.
2 Comments
I just hit this problem today, thank you for the workaround. I can’t seem to find much specifically about it on Extjs.com. What does Ext prescribe we do in these situation?
The solution for object literals is to either Ext.apply({}, this.sharedConfig) or define it inside your constructor instead.
Clearly, it’s more complicated as demonstrated above when dealing with arrays.
I tend to prefer abusing the prototype because it’s nicer to look at. It’s easy to forget the differing behavior because strings, booleans, and integers are unaffected.