PDA

View Full Version : Where do you define listeners for the view which references the ViewController



bclinton
28 Apr 2014, 2:16 PM
How do I define listeners in the view where the ViewController is being referenced? The examples I've seen show listeners defined on components contained in the view, but I haven't seen any examples where listeners are defined on the view itself.

For example, I thought I should be able to do this in a gridpanel config:



controller : 'client-list',
listeners : {
'activate': 'refreshList'
},


But I get an error when the event fires: Ext.util.Event.getFireInfo(): Unable to dynamically resolve method "refreshList"

So, I've been defining them in the initComponent method of the gridpanel like this:



initComponent: function()
{
this.addListener('activate', this.getController().refreshList);
this.addListener('itemcontextmenu', this.getController().showContextMenu);
this.addListener('containercontextmenu', function(view, e) { e.preventDefault(); } );
this.addListener('contextmenu', function(view, e) { e.preventDefault(); } );

this.callParent(arguments);
}


Is this the correct way to define listeners for a view or is there a way to do it in the config of the view?

evant
28 Apr 2014, 2:30 PM
These are a special case because the behaviour can change depending on how they're used.

Consider:



{
xtype: 'container',
controller: 'foo',
items: {
xtype: 'clientlist',
listeners: {foo: 'bar'}
}
}


Writing that code I would (correctly) assume that the listener would look up and find the method in the foo controller. To deal with these boundary cases, in the next release we'll have 2 special scope keywords:



scope: 'this'

Which means only ever resolve the scope to the current object, not even my controller and definitely don't look up the hierarchy



scope: 'controller'

Similar to the above, but the scope always resolves to my direct controller, never myself and not up the hierarchy.

LesJ
29 Apr 2014, 5:52 AM
What is the default scope if not specified?

Carun
2 May 2014, 2:30 PM
It's the view controller of the component (if one is specified) or the first one encountered traveling up in the hierarchy. When not using a view controller, but still want the current component to be the scope for events specified with string names, set the defaultListenerScope property to true.

OhmzTech
6 May 2014, 10:22 AM
How would this work with Ext.Window, where the component has no parent? I haven't been able to find an easy way to add the window to the hierarchy, or at least manually relay all events from the window's children.

Carun
6 May 2014, 10:52 AM
The window will have a View controller. That will capture events fired by all the child components (unless one of them has a view controller specified or has defined the defaultListenerScope to itself).


Here is a short example with a window containing a grid and form. Events from the grid and form will be caught by the view controller (MyViewController/foo) at the window (no need to specify any scope). To capture the events from the Window in the same view controller, specify scope: 'this' as part of the listener configuration.




Ext.define('MyWindow', {
extend : 'Ext.window.Window',


height : 600,
width : 800,
autoShow : true,

controller: 'foo',


items : [{
xtype : 'grid',
reference : 'master',
listeners : {
itemclick : 'onItemClick'
},
columns : []
}, {
xtype : 'form',
reference : 'detail',
listeners : {
dirtyChange : 'onFormDirtyChange'
}
}


],

listeners: {
beforeclose: 'onBeforeClose',
scope: 'this'
}
});






Ext.define('MyViewController', {
extend: 'Ext.app.ViewController',
alias: 'controller.foo',

onItemClick: function () {},

onFormDirtyChange: function () {},

onBeforeClose: function () {}


});


Hope this answers your question.

OhmzTech
6 May 2014, 11:02 AM
Thanks for the response, but I was looking for a way to use a controller that might exist higher up in the hierarchy. For example, I have a panel view linked to a controller. That controller has a method to create the window. I would like to therefore have the controller handle everything starting with that panel and down, including any windows generated from within the panel/controller.

I guess I could just point the window to the same controller and create another instance, seems wasteful though.

evant
6 May 2014, 3:15 PM
You can add a window to a container.

OhmzTech
6 May 2014, 3:51 PM
Thanks for the very straightforward response. I guess I never even considered just adding a window to a component like anything else. Seems to work just fine.

mbajema
24 Jul 2014, 7:53 AM
I tried Carun's example in Sencha Fiddle: https://fiddle.sencha.com/#fiddle/81l. I am getting the same "Unable to dynamically resolve method" error when attempting to close the window. Is this fixed in a different build?

evant answered me here: http://www.sencha.com/forum/showthread.php?289429-scope-this-not-working-for-view-listeners&p=1057489#post1057489. The example has the wrong scope value.

rhubarb65
11 Oct 2014, 3:07 PM
Could somebody expand on

"add a window to a container"

Peter