PDA

View Full Version : Maintaining Component References



r_honey
13 Jul 2010, 12:06 AM
Well, this is not really an extension or a plugin, just a bit of code to make life more easier in large ExtJs applications.

I have always found referring to ExtJs components a hassle, especially in deeply nested layouts. The combination of id, itemId, and ref has not given me the flexibility I wanted.

So, I created a new way of maintaining Component references, that I have discussed here:
http://www.rahulsingla.com/blog/2010/07/maintaining-component-references-in-extjsext-net-applications-part-ii

Animal
13 Jul 2010, 12:12 AM
Page won't load.

r_honey
13 Jul 2010, 1:02 AM
Looks like the server is sluggish currently. Let me check. I will update when the server is back to normal.

r_honey
13 Jul 2010, 2:09 AM
Hi Animal, I believe the server is responding a lot better now.

carl23934
13 Jul 2010, 11:56 AM
This is fantastic! I've been doing this another, and I've been wanting to hook into Ext to be a bit more efficient about it.

Thanks for the concept!!

Animal
14 Jul 2010, 12:59 AM
OK, except there's no reason to introduce yet another ID configuration.

itemId is already there to provide a scoped identifier. And if not specified, it defaults to the ID.

So your code could be




Ext.Component.prototype.initComponent = Ext.Component.prototype.initComponent.createSequence(function() {
var iid = this.getItemId();
if (this.ns && iid) {
if (Ext.isFunction(this.ns.reg)) {
this.ns.reg(iid, this);
} else {
this.ns[iid] = this;
}
}
});


Then



var ns=Rahul.Ext.allocateControlNamespace();
var pn = new Ext.Panel({
title: 'Login',
layout: 'form',
listeners: { show: pnlLoginShown },
ns: ns,
itemId: 'pnlLogin',
items: [{ xtype: 'textfield', fieldLabel: 'Username', ns: ns, itemId: 'txtUsername', listeners: {specialkey:txtLoginSpecialKey} },
{ xtype: 'textfield', fieldLabel: 'password', ns: ns, itemId: 'txtPassword', listeners: { specialkey: txtLoginSpecialKey} }
]
});


But have you seen SamuraiJack's "slots" concept. It's similar but simpler.

r_honey
14 Jul 2010, 1:10 AM
Hmm.. well yes, I should have considered this. Probably, re-using itemId instead of introducing nsName could have been better. But apart from these minor implementation details, overall, this has simplified how I manage references to a large number of components significantly.

r_honey
14 Jul 2010, 1:18 AM
If I recall correctly (I have been using variations of this approach for over a year now, before finally settling on this one), probably one reason why I chose nsName over itemId was better debugging.

As you said Animal, itemId defaults to id if not specified. That means, if I use itemId, every component gets registered to the namespace ns, either with an explicit id, or an auto-generated one (on the lines of ext-genxxxx).

This made it difficult for me while debugging in FireBug & in various IDEs when I set a watch on the namespace and tried to inspect various Components, and those which I did not wish to get registered (lots of labels, layout containers etc, which are always static and I really did not need to access them in code), also showed up, making it difficult to browse through the actual references I was interested in.

Animal
14 Jul 2010, 2:04 AM
Yes, that is true, all Components will get registered to a namespace if you configure them with the ns config.

r_honey
14 Jul 2010, 2:34 AM
Well, I did not want that, and therefore used nsName. If someone doesn't mind getting all components registered, then probably itemId is a better option. In any case, any of these 2 should be lot better and maintainable than refs & stand-alone itemIds (without ns).

Animal
14 Jul 2010, 2:57 AM
Don't want a component registered? Then don't configure it with the ns config!

Simples!

r_honey
14 Jul 2010, 3:20 AM
Hmmm.. smart!! That nullifies everything in favor of nsName (never thought about that).
Looks like itemId is definitely the better way to go now.. If I do not find anything in favor of nsName soon, probably I would myslef move my code in favor of itemId.

carl23934
8 Oct 2010, 10:21 AM
I'm using a bit of a simpler solution that is very similar to yours.

Add the refO property to any component (or any of it's parents) and that component (or any child components) with the itemId property will have a reference to that component set in refO.

I have an example of using this on my blag: http://jsjoy.com/blog/123/dealing-with-references-to-components


Ext.Component.prototype.initComponent = Ext.Component.prototype.initComponent.createSequence(function(){
if(this.refO && this.itemId ){
this.refO[this.itemId] = this;
}else if(this.ownerCt && this.ownerCt.refO ){
if(this.itemId ){
this.ownerCt.refO[this.itemId] = this;
}
if( !this.refO ){
this.refO = this.ownerCt.refO;
}
}
});