PDA

View Full Version : Understand events



t.hoepfner
27 Jul 2011, 5:37 AM
Hi,

I have problems understanding under which conditions a component receives notifications. Some test code below.



<!DOCTYPE html>
<html>
<head>
<title>Event Test</title>
<link href="lib/touch/resources/css/sencha-touch.css" rel="stylesheet" type="text/css"/>
<script src="lib/touch/sencha-touch-debug-w-comments.js" type="text/javascript"></script>

<script type="text/javascript" charset="utf-8">
var listeners = {
'activate': function(panel) {
console.log("activate", panel.id)
},
'deactivate': function(panel) {
console.log("deactivate", panel.id)
}
};
new Ext.Application({
launch: function() {
//new Ext.Carousel({
new Ext.TabPanel({
id: 'root',
fullscreen: true,
listeners: listeners,
items: [
{
id: 'panel_1',
title: "Panel 1",
listeners: listeners,
items: [
{
id: 'panel_1_content',
html: 'Content of first panel',
listeners: listeners
}
]
},
{
id: 'panel_2',
title: "Panel 2",
listeners: listeners,
items: [
{
id: 'panel_2_content',
html: 'Content of second panel',
listeners: listeners
}
]
}
]
});
}
});
</script>
</head>
<body>
</body>
</html>


I would have expected something like the following after starting and switching to the second panel:



activate root
activate panel_1
activate panel_1_content
activate panel_2
activate panel_2_content
deactivate panel_1_content
deactivate panel_1


Instead i only see:



activate panel_1
activate panel_2
deactivate panel_1


So the root component and the child-components are not getting events.

When I change the root to be a Carousel instead of a TabPanel, there are no deactivate events at all:



activate panel_1
activate panel_2


Is this explained somewhere? Is there a way to control event propagation to child components?

Thanks for your help,

Timo

t.hoepfner
1 Aug 2011, 4:03 AM
Answering to my own question:

I found two ways to accomplish what I wanted to do. I my case the particular problem was stopping a playing video when the video became invisible but didn't get the hide/deactivate events because it was wrapped in a Carousel. The first approach uses a component query to move the handling of the events to the parent container.



items: [
{
xtype: 'introcard',
listeners: {
'deactivate': function(panel) {
console.log("deactivate", panel.xtype);
var videos = panel.query(".video");
Ext.each(videos, function(video) {
if (video.playing) {
console.log("Pausing video", video.url);
video.pause();
} else {
console.log("Video already paused ", video.url);
}
});
}
}
},
// ...
]



The other variant is to relay events to child components. The child component then can do the handling by itself, but it is necessary to add the relaying to every level from the root to the actual child:



items: [
{
id: 'panel_1',
title: "Panel 1",
listeners: listeners,
items: [
{
id: 'panel_1_content',
html: 'Content of first panel',
listeners: listeners
}
],
initComponent: function(){
this.superclass().initComponent.call(this);
this.items.each(function(item){
item.relayEvents(this,['activate','beforedeactivate','deactivate']);
}, this);
}
},
// ...
]


I ended up using the first approach. I hope this will help someone.

Timo