ExtJS: Selector for all sub-views of a view - extjs

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.

Related

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

ExtJS Grid SelectionChange is fired in other controller

I have a main application with a left navigation menu. My Main.js controller handles the treepanelselect event where a Tab is added:
onTreepanelSelect: function (selModel, record, index, options) {
var mainPanel = Ext.ComponentQuery.query('mainpanel')[0];
var newTab = mainPanel.items.findBy(
function (tab) {
return tab.title === record.raw.text;
});
if (!newTab) {
newTab = mainPanel.add({
xtype: record.raw.class_name, // this is my View widget name
closable: true,
iconCls: "key",
title: record.raw.text
});
}
mainPanel.setActiveTab(newTab);
},
Two of the Navigation menu items are:
Employee (controller.Employee)
Catalog (controller.Catalog)
controller.Catalog is my controller for managing my catalogs and is 100% separate from controller.Employee (2 different modules)
Here is my controller.Catalog:
refs: [
{
ref: 'grid',
selector: '#gridCatalog'
}],
init: function (application) {
this.control({
'grid': {
selectionchange: this.gridSelectionChange
}
});
},
gridSelectionChange: function (model, records) {
console.log("Catalog Row Selected");
},
So the view.Catalogs has a gridCatalog and on selectionchange I get in my console: Catalog Row Selected.
On the other side, here is my controller.Employee:
refs: [
{
ref: 'grid',
selector: '#gridEmployee'
}
],
init: function (application) {
this.control(
{
'grid': {
itemdblclick: this.gridDoubleClick
}
});
},
gridDoubleClick: function (dv, record, item, index, e) {
// nothing here for the moment.
}
Ok, here is where the Devil comes to scene.
When I run my application, then I click my navigation item "Employee" and my tab is created with the view inside it. Until here we are fine.
But.... when I click one of the rows of my gridEmployee guess what?? I get in my console: Catalog Row Selected.
So, for some reason the controller.Catalog is listening to my gridEmployee... I don't have a selectionchange event handler in my controller.Employee. Those file are even in separate module folders inside my "app" folder.
Any clue on what I'm doing wrong? This is breaking my head :(
Both your controllers are listening to events from any grid since they are both using the grid component query inside init`. Improve your query so that it's not so generic.
init: function (application) {
this.control(
{
// Don't listen to any grid, just #gridEmployee
'#gridEmployee': {
itemdblclick: this.gridDoubleClick
}
});
},
Second file
init: function (application) {
this.control({
// Don't listen to any grid, just #gridCatalog
'#gridCatalog': {
selectionchange: this.gridSelectionChange
}
});
},
You seem to have been under the impression that what you use for the refs affected the component query that is passed into this.control, but it doesn't See http://docs-origin.sencha.com/extjs/4.2.2/#!/api/Ext.app.Controller-method-control

Extjs MVC - having a special cotroller per tab in tabpanel

I have a MainController that listens to events in the entire app (globally).
My app has tab panel, and each panel is very complex and need to have its own controller (a lot of evets).
How will I add a special controller per tab panel to handle its own events?
If youll see bellow. I have the MainController opening new tabs in the method onMenuItemClick.
I want the MainController let other controllers handle the tab opening and tab event listening.
So for example.
MainController call CustomerController.
CustomerController listen to events on the customer tab only.
CustomerController extend BaseTabController.
BaseTabController listen to similar events across all tabs and handle tab opening.
This is what I have so far:
Ext.application({
name: 'App',
controllers: ['MainController'],
stores : ['MainMenuStore'],
autoCreateViewport: true,
appFolder: '/app',
});
Ext.define('App.controller.MainController', {
extend: 'Ext.app.Controller',
refs: [{ ref: 'tabs', selector: 'viewport > #tabs'}],
init: function () {
this.control({
'viewport > #nav': {
itemclick: this.onMenuItemClick
}
});
},
onMenuItemClick: function (view, rec) {
var id = rec.raw.panel;//Can be the controller name for example
var cls = "App.view." + id;
var tabs = this.getTabs();
var tab = tabs.child('#' + id);
console.log(tab);
if (!tab) {
tab = tabs.add(Ext.create(cls, {
itemId: id,
title: rec.get('text')
}));
}
tabs.setActiveTab(tab);
}
});
this is the basic uml that i want to achieve.
Thats exactly what DeftJS is for.
With DeftJs you can give each view its own controller. This will be applied for each instance of your views. Also, your special controllers can inhert from your base controller.
Check out the docs at DeftJS Docs
Example:
View:
Ext.define( 'MyProject.view.tab.Main', {
extend: 'Ext.tab.Panel',
controller: 'MyProject.controller.tab.Main',
...
Controller:
Ext.define( 'MyProject.controller.tab.Main', {
extend: 'Deft.mvc.ViewController',
...

Using ComponentQuery to find a certain Component - extjs

I'm using a controller to initialize a function when a certain panel is rendered. How can i use the ComponentQuery to detect the exact panel without using 'parent > child' finders?
Here's the code:
Ext.define('MC.controller.Description', {
extend: 'Ext.app.Controller',
init: function() {
this.control({
'**what goes here?**': {
render: this.onPanelRendered
}
});
},
onPanelRendered: function() {
console.log('PANEL WAS RENDERED WHOOO');
}
});
use itemId and then do lookups using queryById

How to get plugin from component using component query on Extjs 4.1?

I want to add event listener to plugin on Controller.like http://docs.sencha.com/ext-js/4-1/#!/api/Ext.app.Controller It seems different to get plugin using component query than normal component.
Is it possible to get plugin from component using component query?
Here is my component
Ext.define('App.view.file.List',{
rootVisible: false,
extend:'Ext.tree.Panel',
alias:'widget.filelist',
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop',
allowParentInsert:true
}
},
//etc ...
Can i get treeviewdragdrop plugin using component query like
Ext.define('App.controller.FileManagement', {
extend:'Ext.app.Controller',
stores:['Folder'],
views:['file.List','file.FileManagement'],
refs:[
{ ref:'fileList', selector:'filelist' }
],
init:function () {
this.control({
'filelist > treeviewdragdrop':{drop:this.drop} // <-- here is selector
});
},
// etc ....
You can't because a plugin is not a component, thus no selector will find it.
Also, the drop event is fired by the treeview, so the treeview is really what you want to hook to.
This will work:
init:function () {
this.control({
'filelist > treeview': {drop:this.drop}
});
},
There is no straightforward approach to do that. If I were in your shoes I would, probably, made tree to fire needed event when the plugin fires its event:
// view
Ext.define('App.view.file.List',{
// ...
viewConfig: {
plugins: {
ptype: 'treeviewdragdrop',
pluginId: 'treeviewdragdrop', // <-- id is needed for plugin retrieval
allowParentInsert:true
}
},
initComponent: funcion() {
var me = this;
me.addEvents('viewdrop');
me.callParent(arguments);
me.getPlugin('treeviewdragdrop').on('drop', function(node, data, overModel, dropPosition, eOpts) {
// when plugin fires "drop" event the tree fires its own "viewdrop" event
// which may be handled via ComponentQuery
me.fireEvent('viewdrop', node, data, overModel, dropPosition, eOpts);
});
},
// ...
Controller:
// controller
Ext.define('App.controller.FileManagement', {
// ...
init:function () {
this.control({
'filelist':{viewdrop:this.drop} // <-- here is selector
});
},
// etc ....

Resources