Firing custom event from custom component and handle event in viewController - extjs

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');
}

Related

Can I define a function inside ViewModel and call from Controller in EXT JS

Current scenario is I have data manipulation function inside a class and I call this function when I get data from REST service inside my controller loadData function. Then I update the store of my viewModel.
Now I was wondering Is their a way by which I can concentrate the data manipulation function and store update to view model and from controller I call viewmodel function pass the data from rest service.
Yes you can define function inside of viewmodel and call from controller.
In this FIDDLE, I have created a demo using view-model and controller. I hope this will help you or guide you to achieve your requirement.
Code Snippet
Ext.application({
name: 'MYDEMO',
launch: function () {
Ext.define('FormController', {
extend: 'Ext.app.ViewController',
alias: 'controller.formcntr',
//this will fire on get data button tap
onGetDataButtonTap: function (btn, e, eOpts) {
this.getViewModel().doGetData();
},
//this will fire on set data button tap
onSetDataButtonTap: function (btn, e, eOpts) {
this.getViewModel().doSetData();
}
})
Ext.define('MyViewModel', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myViewModel',
//For setting data inside of viewmodel or somthing diffrent opetraion
doSetData: function (data) {
Ext.Msg.alert('Success', 'doSetData method of ViewModel, called from Controller/view');
//set data from here
//or you can put your logic here whatever you want
//Depend on your requirement
},
//For getting data inside of viewmodel or somthing diffrent opetraion
doGetData: function () {
Ext.Msg.alert('Success', 'doGetData method of ViewModel, called from Controller/view');
//return data from here
//or you can put your logic here whatever you want
//Depend on your requirement
}
});
Ext.create({
xtype: 'panel',
title: 'Users Profile',
fullscreen: true,
layout: 'vbox',
controller: 'formcntr',
viewModel: {
type: 'myViewModel'
},
tbar: [{
text: 'GET Data',
handler: 'onGetDataButtonTap'
}, {
text: 'SET Data',
handler: 'onSetDataButtonTap'
}],
renderTo: Ext.getBody()
});
}
});

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);
}
}
}
})
}
})

Ext JS: Window child component hide event

I have a Window that contains several child components (example only contains a Panel). When I hide this Window, I want the child components to do some processing. Is there an event the child components can listen for when the parent is hidden? I tried using hide, disable, and deactivate, but none of them fired.
This is the example code and Fiddle I'm working with:
var myPanel = Ext.create('Ext.panel.Panel', {
title: 'My Panel'
});
myPanel.on('afterrender', function() {
myPanel.el.on('hide', function() {
alert('el hidden');
}, this);
}, this);
myPanel.on('hide', function() { alert('hidden'); }, this);
myPanel.on('deactivate', function() { alert('hidden'); }, this);
myPanel.on('disable', function() { alert('hidden'); }, this);
var myWindow = Ext.create('Ext.window.Window', {
height: 300,
width: 300,
items: [myPanel],
closeAction: 'hide'
});
var button = Ext.create('Ext.button.Button', {
text: 'Toggle Window',
renderTo: Ext.getBody()
});
button.on('click', function() {
if (myWindow.isVisible()) {
myWindow.hide();
}
else {
myWindow.show();
}
}, this);
When the Window gets hidden, I want to enter the event listeners. I even started experimenting with getting the DOM Element, but there's no such event as hide. I realize I can control the processing from the Window, but I'd rather have each component listen for an event and take care of itself autonomously.
Any thoughts?
As far as i know, you cant listen directly to another component's events, although you could do some processing in a controller and accomplish this.
The most similar approach to what you asked that i could come up with was to listen to the hide event in the parent, and fire the same event in the child component.
-working fiddle:
https://fiddle.sencha.com/#fiddle/c74
you could iterate all children and do what you need.

Listening to events between view controllers

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'
}
}

ExtJS: Selector for all sub-views of a view

Setup: So I have a controller that manages a hierarchy of views. I want my controller to be able to pickup on any events fired within this view hierarchy.
app/view/myView.js
Ext.define('app.view.myView', {
...
alias: 'widget.myview',
buttons: [{
...
handler: function() {
this.fireEvent('someEvent', this, args); // handler in controller
},
...
}]
});
app/controller/myController.js
Ext.define('app.controller.myController', {
...
views: ['myView', ...],
init: function() {
this.control({
'someSelector': { // what does this selector need to be?
someEvent: //handle event
},
...
});
}
});
What does 'someSelector' need to be to accomplish this?
The selectors work in a very similar manner to CSS selectors:
myView *
Any child element at any depth under myView.

Resources