PDA

View Full Version : What is the best practise for extending ExtJs classes?



tayyabah
2 Dec 2010, 10:12 PM
I have made my own extended class for combobox and then used it in my grid extension's toolbar.
When I add listeners in the combo extention then only the render event is fired. But If I add the listener where I am adding this combo in grid toolbar then none of its listeners are called. I dont know where I am doing wrong. Here is the code snippet. Can anybody tell me what is wrong with the code? What is the best practise to extend the extjs classes?
combo extension:

Application.MyCombo = Ext.extend(Ext.form.ComboBox, {
parent: '',
initComponent:function() {
Ext.apply(
this,
{
store: myStore,
displayField:'page',
valueField: 'size',
value: maxPageSize,
mode: 'local',
forceSelection: true,
triggerAction: 'all',
selectOnFocus:true,
emptyText:'Select page size...',
selectOnFocus:true,
width: 120,
listeners: {
render: function(combo){
alert('render');
},
show: function(){
alert("show"); // this method is not called
},
Select: function(){
alert(this.parent);
}
}
});
Application.MyCombo.superclass.initComponent.call(this);
} // eo function initComponent
});
Ext.reg('myCombo', Application.PagerCombo);

Here is the code where I am adding this combo which is a grid extenstion:

Application.card.MyGrid = Ext.extend(Ext.grid.GridPanel, {
initComponent:function() {
Ext.apply(
this,
{
layout: 'fit',
store: ds,
loadMask : {msg: 'Loading ...'},
animCollapse: false,
stripeRows:true,
viewConfig: { forceFit:true },
cm: new xg.ColumnModel(
[
new Ext.grid.RowNumberer(),
//my column model
]
),
sm: new Ext.grid.RowSelectionModel({
singleSelect: true,
listeners: {
rowselect: function(sm, row, rec) {
// Ext.MessageBox.alert( "Row: " + row + " Data: " + rec.data.activityId);
}
}
})
,
bbar: [new Application.PagerCombo({
parent : 'parent',
// if I define the listeners here then none of them are called

})]
});
Application.card.InsuranceContractGrid.superclass.initComponent.call(this);
} // eo function initComponent
});

Ext.reg('mygrid', Application.card.MyGrid);

Please tell me where am I doing wrong?

Animal
2 Dec 2010, 11:43 PM
Why did you think you needed to extend to get a grid?

Why don't you just instantiate a grid? (Was it because you found some code you could copy/paste without understanding hmm?)

tayyabah
2 Dec 2010, 11:45 PM
I havn't added my custom methods in the code snippet. I needed some custom methods in the grid thats why extended the classes. Can you please answer what I asked for?

Animal
2 Dec 2010, 11:46 PM
So this whole thing is about why show is not being fired?

because the Combo is not being SHOWN. It's never hidden. There is never a SHOW operation performed on it.

tayyabah
2 Dec 2010, 11:51 PM
Then why the combo's render method doesn't fire when I add its render listener in the MyGrid toolbar?
Can you please also give an example of what is the best way of extending the extjs class? how to override the existing methods etc?

Animal
3 Dec 2010, 12:38 AM
You cannot add listeners in initComponent.

In fact I do not like extending using initComponent.

initComponent is called at a particular point in the ongoing construction. Things are done before and after it. And so some things cannot be done there.

I would advise you to provide a constructor.

I know this is against the copy/paste site you found, but... well... I am right.

Here's a little something I wrote for questions like this: http://www.sencha.com/learn/Tutorial:Creating_new_UI_controls

Screamy
3 Dec 2010, 9:46 AM
Excellent article, Animal. Wish I would have stumbled across this sooner...

mschwartz
3 Dec 2010, 11:57 AM
You cannot add listeners in initComponent.

In fact I do not like extending using initComponent.

initComponent is called at a particular point in the ongoing construction. Things are done before and after it. And so some things cannot be done there.

I would advise you to provide a constructor.

I know this is against the copy/paste site you found, but... well... I am right.

Here's a little something I wrote for questions like this: http://www.sencha.com/learn/Tutorial:Creating_new_UI_controls

Are you sure you can't add listeners in initComponent() ?

I add them all the time and they work.

Just have to do it after calling the superclass.initComponent. Something like:



myComponent.superclass.initComponent.apply(this, arguments);
this.on({
click: function(e) {
alert('clicked!');
}
});


works for me.

Animal
3 Dec 2010, 1:01 PM
Yes, you can add them.

You cannot apply listeners to this though, which is the problem at hand.

darthwes
3 Dec 2010, 2:58 PM
@Animal, your article was the turning point for my understanding of Ext.extend, keep on pushing!

@OP, your problem is that you need to put the listeners config onto the config object prior to calling the superclass's constructor, not after, and your going to hit problems if you declared listeners on the config before you passed it to the constructor. What you'll need to do is apply your listeners onto the cfg.listeners object. You'll be doing something like



Ext.apply(cfg.listeners, {
'render': ...,
'show': ...
});

_in the constructor_ and you'll have to code around the case when cfg.listeners is undeclared (declare it
cfg.listeners = {};)

Alternatively, you could use the 'addListener' method (which has a shortcut method called "on") at any time (during initComponent or constructor or just willy nilly whenever you like).

Condor
4 Dec 2010, 1:13 AM
I wouldn't try to modify the passed in listener object. When extending a class I recommend something like:

MyComponent = Ext.extend(Ext.Component, {
initComponent: function(){
var config = {
// default config, but no 'listeners' or 'id'
};
Ext.apply(this.initialConfig, config);
Ext.apply(this, config);
MyComponent.superclass.initComponent.call(this);
this.on({
// 'listeners' here
}, this);
}
});
(actually I agree with Animal on using constructor instead of initComponent, but I'm tired of going against the flow)