ExtJS 3.0 RC1.1 includes some interesting improvements under the hood. First, Ext.Button is now a Component, so the ownerCt property works as you’d expect.
More interestingly, there is now a ref property for Component which is initialized during the render portion of the Component lifecycle. It allows you to inject a back reference into each ownerCt all the way back to your Viewport, Window, or whatever. Usage is surpisingly intuitive.
initRef : function(){ if(this.ref){ var levels = this.ref.split('/'); var last = levels.length, i = 0; var t = this; while(i < last){ if(t.ownerCt){ t = t.ownerCt; } i++; } t[levels[--i]] = this; } },
A common example is an Ext.Button, living inside an Ext.Toolbar assigned to an Ext.grid.GridPanel’s tbar property. Prior to ExtJS 3.0, you’d need to give your button an id and reference it via Ext.getCmp().
myGrid = Ext.extend(Ext.grid.GridPanel, { title:'myGrid', initComponent:function() { this.store = myStore; // use your imagination this.tbar = [ {text:'disable me', id:'button', disabled:true} ]; myGrid.superclass.initComponent.apply(this, arguments); this.getStore().on('load', function() { Ext.getCmp('button').enable(); }, this); } });
I don’t find that particularly clean. Another possibility is to instantiate the button so you have an existing reference to it, then you can act upon that in your store event handler. I don’t like that very much, either. Fortunately, there’s an excellent alternative.
myGrid = Ext.extend(Ext.grid.GridPanel, { title:'myGrid', initComponent:function() { this.store = myStore; // you sense a complete store config here this.tbar = [ {text:'enable me', disabled:true, ref:'../Button'} ]; myGrid.superclass.initComponent.apply(this, arguments); this.getStore().on('load', function() { //this['Button'].enable(); // More natural this.Button.enable(); }, this); } });
Use care as to not override any existing properties in whatever ownerCt you choose to provide a back reference to! Using the key store, for example, would cause some undo confusion when your store object is overridden when the button renders and is replaced with your button object.
3 Comments
Nice tip, thanks for sharing!
I’d have gone with lowercase as is the convention for properties, so ref: ‘../button’
Then simply “this.button.enable()”
Yes, that was my first instinct. I didn’t want to collide with other properties.