PDA

View Full Version : create event



jep
13 Oct 2011, 4:26 PM
I posted a question to the premium forum and thought I'd repost the answer I came up with here in case anyone else finds it useful.

I wanted a "create" event that happened on all component creation. Sometimes I needed stuff set up on object creation, but initComponent fires before the object is full set up (this.down() fails, for one). So I came up with this:



Ext.override(Ext.lib.Component, {
plugins:[{
init:function (cmp) {
cmp.addEvents('create');
cmp.fireEvent('create', cmp);
}
}]
});

Ext.setup({
onReady : function() {

var mainPnl = new Ext.Panel({
layout:'fit',
fullscreen: true,
html:'main panel',
dockedItems:{itemId:'tb', xtype:'toolbar', dock:'top'},
listeners:{
create:function (component) { console.log('create event', component, this, this.down('#tb').itemId); }
}
});
}
});


Notice any problems?

AndreaCammarata
14 Oct 2011, 5:54 AM
Hi jep,
I'm sorry but you can't do that!
Even if you was able to add your plugins in that way, if you take a look at the Ext.Component source code, you will notice for sure that plugins are always initializated after calling the initComponent function inside the component constructor.

Try to explain me why you want to do that, and I will try to help you.

Hope this helps.

jep
14 Oct 2011, 7:25 AM
But, I'm doing it, so I'm not sure why you say I can't. It works great. :)

The whole point I was making is that initComponent happens too early in the constructor. I needed something that happens later. Here's the Ext.lib.Component source:



constructor : function(config) {
config = config || {};
this.initialConfig = config;
Ext.apply(this, config);

this.addEvents(
// trimmed for brevity
);

this.getId();

this.mons = [];
this.additionalCls = [];
this.renderData = this.renderData || {};
this.renderSelectors = this.renderSelectors || {};

this.initComponent();

// ititComponent gets a chance to change the id property before registering
Ext.ComponentMgr.register(this);

// Dont pass the config so that it is not applied to 'this' again
Ext.lib.Component.superclass.constructor.call(this);

// Move this into Observable?
if (this.plugins) {
this.plugins = [].concat(this.plugins);
for (var i = 0, len = this.plugins.length; i < len; i++) {
this.plugins[i] = this.initPlugin(this.plugins[i]);
}
}

// This won't work in Touch
if (this.applyTo) {
this.applyToMarkup(this.applyTo);
delete this.applyTo;
}
else if (this.renderTo) {
this.render(this.renderTo);
delete this.renderTo;
}

if (Ext.isDefined(this.disabledClass)) {
throw "Component: disabledClass has been deprecated. Please use disabledCls.";
}
},


Notice this:


this.initComponent();

// ititComponent gets a chance to change the id property before registering
Ext.ComponentMgr.register(this);


It's problematic that initComponent gets called before Ext.ComponentMgr.register(this), because this.down() won't work until the component is registered. I needed to use this.down() in some of my code that would have went in initComponent.

If you instead code my example like this:



Ext.setup({
onReady : function() {

var mainPnl = new Ext.Panel({
layout:'fit',
fullscreen: true,
html:'main panel',
dockedItems:{itemId:'tb', xtype:'toolbar', dock:'top'},
initComponent:function (component) { console.log('create event', component, this, this.down('#tb').itemId); }
});
}
});


You get this error:
Uncaught TypeError: Cannot read property 'items' of undefined

So initComponent simply won't work when I need to use this.down().

Instead, I tried registering and firing an event in initComponent. Well, that doesn't work either because initComponent happens before listeners are read in from the config. That happens in Ext.lib.Component.superclass.constructor.call(this).

Given all that, this seems like the perfect solution and is working great for me. Can you explain why I can't do it?

jep
3 Nov 2011, 2:20 PM
Any further thoughts on this, Andrea? Was it just a misunderstanding where I wasn't clear on what I was trying to do?