PDA

View Full Version : Listeners / Event management in an



fabads
4 Aug 2010, 3:13 AM
Hello,

I need your advice to manage events and listeners in an extension.
I used the tutorials proposed in the Learning Center to develop an application I'd like modular. So I use extensions mechanisms.

In the initcomponent, I use Ext.apply to create underlying components of my extension (tabpanel, chart, datefields ...). I don't know if it is the best way to do.

Let's take an example :


W3h.panels.GraphViewer = Ext.extend(Ext.Container,{
initComponent: function(){
var store = new Ext.data.JsonStore({ ... });

Ext.apply(this, {
layout:'fit',
items: new Ext.TabPanel({
activeTab: 0,
plain:true,
defaults:{autoScroll: true},

items:[
{
title: 'Day',
tbar: {
items: [
{
text: 'previous',
handler: function(){
...
myFunction();
}
},
{
xtype: 'datefieldplus',
...
listeners: {
'afterdateclick':function(picker, date){
...
myFunction();
}
}
},
{
text: '',
iconCls: 'next',
handler: function(){
...
myFunction();
}
},
]
},
...
}]
})
});
W3h.panels.GraphViewer.superclass.initComponent.call(this);
}

});
I'd like to call a function (myFunction()) in the button handler and in the datefield listener. But if I create the function at the extension level, I've got an error.

What is the best way to do that ?

Thx.

Animal
4 Aug 2010, 3:15 AM
Well, move outside the extend-to-configure template you've followed and actually implement a class method!

fabads
4 Aug 2010, 3:23 AM
Any recommended readings or examples to start on good basis ?

Animal
4 Aug 2010, 3:58 AM
For what? You surely know how to use Ext.extend because you are using it.

Add some methods.

fabads
4 Aug 2010, 4:14 AM
I'm afraid to not catch the point.
I'm using Ext.Extend but with no pretention, I'm still a beginner.
I tried to declare a method in the extension (myfunction: function(){alert('test');}) , but It does not work when I call this.myfunction() in the listener or handler of the above example.

Condor
4 Aug 2010, 4:24 AM
You don't call 'this.myfunction' in an event handler! this.myfunction should BE the event handler.

(and you need to specify a scope, so 'this' is correct inside myfunction)

fabads
4 Aug 2010, 4:30 AM
Right, I'm ok with that but in fact, I have some common behaviours in the button handler and in the datefieldplus listener. Shall I need to duplicate the code ?

Animal
4 Aug 2010, 4:38 AM
Route the listener directly to one function, then branch to other handling member functions from there.

VinylFox
4 Aug 2010, 5:01 AM
Code always helps me to understand things better....so I hope this helps...


W3h.panels.GraphViewer = Ext.extend(Ext.Container,{
initComponent: function(){
var store = new Ext.data.JsonStore({ ... });

Ext.apply(this, {
layout:'fit',
items: new Ext.TabPanel({
activeTab: 0,
plain:true,
defaults:{autoScroll: true},

items:[
{
title: 'Day',
tbar: {
items: [
{
text: 'previous',
handler: this.previousFunction,
scope: this
},
{
xtype: 'datefieldplus',
...
listeners: {
'afterdateclick':this.dateClickFunction,
scope: this
}
},
{
text: '',
iconCls: 'next',
handler: this.nextFunction,
scope: this
},
]
},
...
}]
})
});
W3h.panels.GraphViewer.superclass.initComponent.call(this);
},
dateClickFunction: function(){
// do something for date click
},
previousFunction: function(){
// do something for previous
this.go(-1);
},
nextFunction: function(){
// do something for next
this.go(1);
},
go: function(i){
// handle movement
}

});

The methods that get executed for your handlers are part of the class your extending, from within these methods on the class you can call other methods that do this or that - make sense now?

PS. i did not test this code, just typed it out.

fabads
4 Aug 2010, 5:07 AM
Do you mean something like that:


W3h.panels.GraphViewer = Ext.extend(Ext.Container,{
afterdateclick: function(...){
...
myCommonCode();
},

myBtnHandler: function(...){
...
myCommonCode();
},

myCommonCode: function(...) {
...
}

initComponent: function(){
var store = new Ext.data.JsonStore({ ... });

Ext.apply(this, {
layout:'fit',
items: new Ext.TabPanel({
activeTab: 0,
plain:true,
defaults:{autoScroll: true},

items:[
{
title: 'Day',
tbar: {
items: [
{
text: 'previous',
handler: this.myBtnHandler
},
{
xtype: 'datefieldplus',
...
listeners: {
'afterdateclick':{fn:this.afterdateclick, scope:this}
}
},
{
text: '',
iconCls: 'next',
handler: this.myBtnHandler
},
]
},
...
}]
})
});
W3h.panels.GraphViewer.superclass.initComponent.call(this);
}

});

VinylFox
4 Aug 2010, 6:34 AM
Do you mean something like that:

No.

Your buttons need scope so that the 'myCommonCode' method can be called.

So scope the button to 'this' and change where you call 'myCommonCode();' to be 'this.myCommonCode();' instead

Remember - Scope, scope and more scope.

fabads
4 Aug 2010, 7:35 AM
No.

Your buttons need scope so that the 'myCommonCode' method can be called.

So scope the button to 'this' and change where you call 'myCommonCode();' to be 'this.myCommonCode();' instead

Remember - Scope, scope and more scope.

I'm sorry, my answer was to Animal. I did not see your answer with the example. It works fine now and I understand why :)

Thank you very very much to the support community !


I have another question and I know there is a debate in an "expert threads" on this forum about Ext.getCmp. In my handler function, I have to retrieve information (for example the date of the datefield).

What's the proper way to access the data from my extension?
For the moment I use ext.getCmp:

onPreviousDayClick: function(){
var df = Ext.getCmp('datefield');
df.setValue(new Date(df.getValue()).add(Date.DAY, -1));
},
Is it better to use the OO way instead of xtype (df= new datefieldplus ...)
I saw also there is a way through ownerCt or something like that but I'm a little bit flooded !

VinylFox
4 Aug 2010, 8:17 AM
You can use 'ref', though it seems like the Sencha team does not like ref and is phasing it out. I like using ref though.

Just add a ref to your field... (you will need to adjust the number of '../')

{
xtype: 'datefieldplus',
ref: '../../df',
...
listeners: {
'afterdateclick':this.dateClickFunction,
scope: this
}
},

Then change your method to...

onPreviousDayClick: function(){
this.df.setValue(new Date(this.df.getValue()).add(Date.DAY, -1));
},

Another option is to add your own reference in the scope to this field in initComponent...


W3h.panels.GraphViewer = Ext.extend(Ext.Container,{
initComponent: function(){
var store = new Ext.data.JsonStore({ ... });

this.dt = new Ext.form.DateField({
...
listeners: {
'afterdateclick':this.dateClickFunction,
scope: this
}
});

Ext.apply(this, {
layout:'fit',
items: new Ext.TabPanel({
activeTab: 0,
plain:true,
defaults:{autoScroll: true},

items:[
{
title: 'Day',
tbar: {
items: [
{
text: 'previous',
handler: this.previousFunction,
scope: this
},
this.dt,
{
text: '',
iconCls: 'next',
handler: this.nextFunction,
scope: this
},
]
},
...
}]
})
});
W3h.panels.GraphViewer.superclass.initComponent.call(this);
},
dateClickFunction: function(){
// do something for date click
},
previousFunction: function(){
// do something for previous
this.go(-1);
},
nextFunction: function(){
// do something for next
this.go(1);
},
go: function(i){
// handle movement
}

});

fabads
5 Aug 2010, 3:48 AM
Well ! Thx a lot. I used your second method and it works fine now.