Using ComponentQuery to find a certain Component - extjs - 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

Related

Why the refs to itemId cannot trigger the initialize event in Sencha Touch?

This is the controller code:
Ext.define('XXX.controller.XXX', {
extend: 'Ext.app.Controller',
config: {
views: ['CustomView','CarouselView'],
refs: {
custom: "carouselview #customid"
},
control: {
custom: {
initialize : function() {
alert("it's loading")
}
}
}
},
launch: function(){
Ext.Viewport.add(Ext.create('XXX.view.CustomView'));
console.log(this.getCustom()) // ——> This works, it is not undefined
}
});
and this is the carousel view code:
Ext.define('XXX.view.CarouselView', {
extend: 'Ext.Carousel',
xtype: 'carouselview',
defaults: {
styleHtmlContent: true
},
config:{
direction: 'horizontal',
items: [
{
xtype: 'customview',
itemId: 'customid'
}
]
}
});
Now it's the customview :
Ext.define('XXX.view.CustomView', {
extend: 'Ext.Panel',
xtype: 'customview',
config: {
tpl: XXX
}
});
in the controllers's launch function, it can log the right value, but the initialize event can't be triggered.
And if i change refs to { custom: "customview" }, the initialize event can be triggered.
IMHO you (and someone answered below) misunderstand the use of itemId config.
Here is the difference between id and itemId:
id is the global identifier of a component. It can be used directly as a selector in Ext.ComponentQuery class which refs uses behind the scene. So if you want something like "carouselview #customid", you have to use id instead of itemId.
itemId is the global identifier within a class from which the component derives from. For example, assume that you have an Ext.Button with itemId: "myCustomButton", then you can have access to it via this refs: button#myCustomButton (please note that there's no space between them). This way, Ext.ComponentQuery first looks for all components xtyped button, then find the instance with that itemId.
So, if you want to use some string as "first-class" selector, you will have to use id. If you want to use itemId, you may want to always include its xtype before the itemId. Therefore, 2 possible solutions are:
First solution (still use itemId): custom: "carouselview customview#customid"
Second solution: keep your refs, but change #customid from itemId to id
Hope this helps.
UPDATE:
Just figured out that you are trying to initialize on something that get's the itemId on initialize :) Sorry, took me some time.
Basically the fireEvent('initialize') has already been in the past when you are trying to listen to it in the controller.
Use the xtype to initialize or simply:
Ext.define('XXX.view.CustomView', {
extend: 'Ext.Panel',
xtype: 'customview',
config: {
tpl: XXX
},
initialize: function() { // good way to use initialize inside the view, as it belongs to the view and there is not user input handled
}
});
OR
Ext.define('XXX.controller.XXX', {
extend: 'Ext.app.Controller',
config: {
views: ['CustomView','CarouselView'],
refs: {
custom: ".carouselview .customview" // --> HERE use this
},
control: {
custom: {
initialize : function() {
alert("it's loading") // Yeah, now you are getting here
}
}
}
},
launch: function(){ // --> this will be the same as if you are placing it in app.js launch
Ext.Viewport.add(Ext.create('XXX.view.CustomView')); // --> here the initialize happends and this.getCustom() does not yet exists
console.log(this.getCustom()) // ——> here this.getCustom() exists
}
});

Ext Js : Hide all element or items inside container

I have multiple container with field. Basically when container is hidden all field's are not visible. but I was checked "hidden" property or "isHidden()" method of field. I am getting as false.
I want make it as true when container is hidden and false when it is visible.
How to make field are hidden and show by using override
Your question is very hard to read. (Poor English) But if I understand correctly you hide a container with fields. If you then check the isHidden() of one of the fields, it returns false. That is standard Ext behavior. The container is hidden not the fields. What you can do is query down and set the fields hidden.
E.g.
Ext.define('MyCustomContainer', {
extend: 'Ext.Container',
hide: function () {
var me = this;
Ext.each(me.query('field'), function (field) {
field.hide();
});
me.callParent(arguments);
},
show: function () {
var me = this;
Ext.each(me.query('field'), function (field) {
field.show();
});
me.callParent(arguments);
}
});
You ask:
I don't want to create custom component. Can I do same thing by using override?
Yes you can!
I hope you don't have an Ext.Container as type it's kind of dirty overriding it for ALL containers, but it will work... => it would be better to replace Ext.Container with the specific type of your container...
Ext.define('YourApp.override.Container', {
override: 'Ext.Container',
hide: function () {
var me = this;
Ext.each(me.query('field'), function (field) {
field.hide();
});
me.callParent(arguments);
},
show: function () {
var me = this;
Ext.each(me.query('field'), function (field) {
field.show();
});
me.callParent(arguments);
}
});

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: 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.

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