Listening to events between view controllers - extjs

I am having trouble trying to figure out how to listen to events fired in one View Controller from another ViewController.
My grid component defines a Listener
selModel: {
listeners: {
selectionchange: 'onChemClick'
}
},
and my ViewController(called chemslist) has the function that fires another event
onChemClick: function(view, selected) {
console.log("before firing");
this.fireEvent('canvasData', this, selected.length);
console.log("after firing");
console.log(selected);
}
I have another controller that actually listens to this event and shows the data.
Ext.define('view.canvas.CanvasController', {
extend: 'Ext.app.ViewController',
alias: 'controller.canvas',
listen: {
controller: {
chemslist: {
canvasData: 'onCanvasData'
}
}
},
onCanvasData: function() {
console.log("At Fire");
}
});
For some reason I can't figure out why the CanvasController is not able to listen to the event. I did also go through the Ticket example and looked at how the events are fired and other viewControllers listen to them.
Also What would be a best practice if a selection on a grid in one region causes a lot of changes in another panel?, should the event be fired as a global so that all the components would listen to it ? or should i listen to it in the main Controller(not a ViewController) and generate the components based on the event ?
Thanks!

The docs say:
selectors are either Controller's id or '*' wildcard for any Controller.
Contrary to intuition, we are not supposed to assign any id or itemId to the controller we want to listen to but the id is automatically created by Application and the id equals to controller class name.
I've made simple example - button, 2 controllers C1 listening to button and C2 listening to C1.

Event handling is also working between ViewControllers, but you need to provide the controller's id in the listen config (as Saki stated), for your example the firing ViewController:
Ext.define('Edsp.view.chemslist.ChemsListController', {
extend: 'Ext.app.ViewController',
alias: 'controller.chemslist',
id: 'chemslist',
The listening ViewController looks like this:
Ext.define('Edsp.view.canvas.CanvasController', {
extend: 'Ext.app.ViewController',
alias: 'controller.canvas',
listen: {
controller: {
'#chemslist': {
canvasData: 'onCanvasData'
}
}
},

Small correction, id does not need a hash, in fact will not work with it, should be:
listen: {
controller: {
'chemslist': {
canvasData: 'onCanvasData'
}
}

Related

Extjs 6 Modern - How to execute function in controller from view?

In controller
listen: {
global: {
'ontest': 'ontestfunction'
}
},
ontestfunction: function(){
alert('oks 31');
}
In view
listeners: {
element: 'element',
click: function(){
Ext.GlobalEvents.fireEvent('ontest');
}
}
It is the only way I've found to work, you know some other way?
You can get any controller using Ext.app.Controller.getController.
Since application is derived from controller, all you have to know is the name of your app and the desired controller; and calling the function is a piece of cake:
var configController = MyAppName.app.getController("MyAppName.controller.Configuration");
configController.ontestfunction();
Since you're using EXT 6, I assume you're using viewcontrollers and not controllers.
Ext is going to resolve the scope as the view's controller automatically, no need to write any extra code.
First make sure you define the viewcontroller as the controller of the view:
controller: 'aliasofviewcontroller'
after that you can basically assign any of the controllers functions to the handlers of the components on the view.
Let's say you have the following function in your controller:
onClickCustomHandler:function(e){
...
}
Using the following syntax, the function is going to get called every time you're button is clicked:
Ext.create('Ext.Button', {
text: 'My button',
handler: 'onClickCustomHandler'
});
Or using xtype:
{
xtype:'button',
text:'My button',
handler: 'onClickCustomHandler'
}
For further reading: http://docs.sencha.com/extjs/6.0.2/guides/application_architecture/view_controllers.html

Firing custom event from custom component and handle event in viewController

I have created a custom component that extends from Ext.Panel. I have added a click listener to the custom component so that when it's clicked it will fire an event. I am instantiating the custom component in a view and I want to handle the event thats fired from the custom component in the viewController associated with that view.
However, when I fire the event, it's not bubbling up to the viewController. Is there a way to fire an event on the global scope? How do I go about handling an event in a viewController where the component that fires the event is instantiated in the view associated with the view controller?
My custom component looks somthing like so:
Ext.define('MyApp.ux.CustomComponent', {
extend: 'Ext.Panel',
xtype: 'custom-component'
initComponent: function() {
var me = this;
me.callParent();
me.addListener({
'render': function(panel) {
panel.body.on('click', function() {
me.fireEvent('customEventName');
});
}
});
}
});
I am instantiating my custom component in a view like so:
Ext.define('MyApp.view.main.Main', {
extend: 'Ext.container.Container',
controller: 'main'
items: [{
xtype: 'custom-component'
}]
});
And in my viewController (for the view that im instantiating my custom component in) I have the following listener:
customEventName: function () {
console.log('I have been fired');
}
View controllers listen for child item listeners, but not manually fired events. So, you need to use listener config for this like this e.g.
Ext.define('MyApp.view.main.Main', {
extend: 'Ext.container.Container',
controller: 'main'
items: [{
xtype: 'custom-component',
listeners: {
customEventName: 'customHandlerNameInController'
}
}]
});
Now when you fire your custom event, your view controller method must work.
To fire events globally, you can use:
Ext.GlobalEvents.fireEvent('eventName', {args});
http://docs.sencha.com/extjs/6.0/6.0.0-classic/#!/api/Ext.GlobalEvents-method-fireEvent
Edit:
You can try a workaround:
Ext.GlobalEvents.fireEvent('customEventName');
In your controller:
listen: {
global: {
'customEventName': 'onClick'
}
}
onClick: function(){
Ext.log('click happened');
}

Listen for other components events

I am developing a component that act as an application taskbar.
Currently, I have a class App (that's not the fully qualified class name) that extends Ext.window.Window which on init it creates a button with reference to itself and renders it to the taskbar. But I don't think this is the application's responsibility to add itself to the taskbar, but rather it is the taskbar's responsibility to listen for applications initialization and create a reference to them in it.
So, in the taskbar's ViewController I need to capture all the render events fired by any App instance. I can't find a way to do that in the documentation.
How can I do it? Or is there a better way of doing it?
ExtJS 5.1
Define an Ext.app.EventDomain to monitor Ext.window.Window events.
Ext.define('MyApp.app.domain.Taskbar', {
extend: 'Ext.app.EventDomain',
singleton: true,
requires: [
'Ext.window.Window'
],
// catalog the domain in the Ext.app.EventDomain.instances map
type: 'taskbar',
idProperty: 'id',
constructor: function() {
this.callParent();
this.monitor( Ext.window.Window );
}
})
Define a controller to listen for the window render event.
Ext.define('MyApp.controller.Taskbar', {
extend: 'Ext.app.Controller',
requires : [
'MyApp.app.domain.Taskbar'
],
init: function() {
this.listen({
taskbar: {
// wildcard selector to match any window
'*':{
render: function(window, eOpts){
console.log('render window: ' + window.id);
}
}
}
})
}
})

How to properly add listener for a control in controller?

I can successfully add a listener to the painted event in the view for a selectfield. But, how do I do this in the controller?
control: {
"#form #field": {
painted: 'onPainted'
}
}
// omitted onPainted method that logs message in console
This doesn't work. However, directly adding a listener in the view works.
// in the view for the selectfield (works)
listeners: {
painted: function() {
console.log("Painted");
}
}
What am I missing?
From a comment in the docs:
This event is not bubbled up to the controller, "for performance reasons".

how to call a view from a controller in extjs mvc 4

I have RowEdit in my view. I would like to able to call the controller so i can save the model.
My View
var rowEditing = Ext.create('Ext.grid.plugin.RowEditing', {
clicksToMoveEditor: 1,
autoCancel: false,
listeners: {
afteredit: function () {
// i want to call the controller from here
}
}
});
Ext.define('Pandora.view.MaterialsList', {
extend: 'Ext.grid.Panel',
alias: 'widget.materialslist',
store: 'Materials',
title: 'Materials',
plugins: [rowEditing]
}
I appreciate i may be going about this the wrong way and should be trying to catch this event in my controller but I have been unable to catch the event in my controller.
According to the docs, the event you want is edit not afteredit. Try listening to that in your controller.
In case you still want to be able to do what you've asked:
In one of your controllers, in the init code, you will need to assign the application to a global variable. APP = this.application
Then, anywhere in your application, you can say APP.getController('myController').myMethod()

Resources