ExtJS 3.0 ref and button ownerCt

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

  1. Joshua
    Posted 5/22/2009 at 6:49 am | Permalink

    Nice tip, thanks for sharing!

  2. Animal
    Posted 5/22/2009 at 9:07 am | Permalink

    I’d have gone with lowercase as is the convention for properties, so ref: ‘../button’

    Then simply “this.button.enable()”

  3. Posted 5/22/2009 at 12:06 pm | Permalink

    Yes, that was my first instinct. I didn’t want to collide with other properties.

Post a Comment

Your email is never shared. Required fields are marked *

*
*