Extjs 4.2: 'hasListeners' property of Ext Component's(panel) - extjs

I have a panel with around 10 items. For all those items I have implemented "after render" event handler in respective controllers of each item.
This is how I have registered afterrender events in Controller's init method:
init: function() {
this.control({
'#myFirstPanel': {
afterrender: this.afterrender
}
});
}
My panel code is like:
Ext.define('App.view.popUpWindow', {
extend: 'Ext.panel.Panel',
initComponent: function(){
this.callParent();
},
id: 'popup',
layout: 'fit',
items: [
{
xtype: 'panel'
items: [
{
// One of my custom component
xtype:'FirstGrid'
}....//10 items in total
]
}]
});
When I get hasListeners property of my panel's object after my app loads by following code
Ext.getCmp('popup').hasListeners
It returns me this object
{afterrender: 10, tabchange: 1}
Now when I destroy my panel by this command
Ext.getCmp('popup').destroy()
and open my app again(my app is a sub Extjs app of a another Extjs app)
Ext.getCmp('popup').hasListeners
It returns me this object
{afterrender: 20, tabchange: 2}
My question is that why even after call to destroy(), hasListeners is some how keeping record of old Listeners? I know this object doesn't show the number of listener (I read api) but what is going here then?
Can someone explain this to me? As I have to manually remove old listeners(my other question about this), why not .destroy() is automatically destroying all references?
Thank you.

Related

Extend a grid with listeners

I'm trying to extend Ext.grid.Panel to build one who would come with "prebuild" listeners (that will check for a store, and tell the store to add the nulber of records in the title of the gridpanel). I'm stuck at the very beginning of this process, I can't find the right way to do this despite browsing the doc for a while:
//Extending a grid with a simple hello world...
Ext.define('MIS.Ext.GridExtraHeaderData', {
extend: 'Ext.grid.Panel',
alias: 'widget.gridExtraHeaderData',
listeners:{
beforerender:function(){
console.log('hello world');
}
}
});
I replaced Ext.grid.Panel with MIS.Ext.GridExtraHeaderData and the grid is working very well, but I can't see any "hello world" in my console...
When I look to the created object, I have "listeners:null" and "proto.listeners" filled.
I tried constructor, initComponent, no success.
Don't attempt to bind them in the listeners block, since they are going to clash with any user defined listeners. Instead, bind them in code:
Ext.define('MIS.Ext.GridExtraHeaderData', {
extend: 'Ext.grid.Panel',
alias: 'widget.gridExtraHeaderData',
initComponent: function() {
this.on('beforerender', function() {
}, this);
this.callParent();
}
});

Passing data to another view from controller and set a label's value in sencha touch

I have a controller, and I want to pass a simple string value to the next View.
For that, I am creating the View like this.
var nextView = Ext.create('MyApp.view.NextView', {
content: 'value'
});
Ext.Viewport.add(nextView);
Ext.Viewport.animateActiveItem(nextView, {
type: 'slide',
direction: 'left'
});
On the NextView, I have a label and I want to set the HTML property of the label to the value that I am passing from the controller. ie. value.
My NextView looks like this.
Ext.define('MyApp.view.NextView', {
extend: 'Ext.form.Panel',
config: {
content: 'null',
items: [{
xtype: 'label',
html: 'value'
}]
}
});
I am not sure how to proceed from here. I can't have the NextView as a form. I just need to pass one string value in this situation.
What's the best way to achieve this?
Use initialize method to access config data like this:
Ext.define('MyApp.view.NextView', {
extend: 'Ext.form.Panel',
config: {
content: 'null',
items: [
{
xtype: 'label',
html: 'value'
}
]
},
initialize : function(){
this.callParent();
var val = this.config.content;
this.down('label').setHtml(val);
}
});
PS Feel free to use your favourite selector in down function
I know the question has been answered. But I just digged up a pretty natural way to pass data from controller to a view (using view's constructor). I use this in my integration of web desktop to my app.
In controller, pass data to the constructor of the view as followed:
loiTab = Ext.create('Iip.view.giips.admission.DetailedLoiTab', {closable: true, selectedLoiData: selected[0].data});
In the view, spin up a constructor as followed:
constructor: function(selectedLoiData) {
Ext.applyIf(this, selectedLoiData);
this.callParent();
},
The following method lives in the same file as the constructor. You can access selectedLoiData from any where in the view the constructor lives as followed:
initComponent: function(){
console.log(this.selectedLoiData);
}

getRootNode() is not a function

I try to develop an app with MVC architecture. I've the following Controller code:
Ext.define('PM.controller.Projects', {
extend: 'Ext.app.Controller',
models: ['Project'],
stores: ['Projects'],
views: [
'projects.Tree',
'Toolbar',
],
init: function(config) {
var tree = this.getProjectsTreeView();
var rootNode = tree.getRootNode();
console.log(rootNode);
this.callParent(config);
}
});
And this view code:
Ext.define('PM.view.projects.Tree', {
extend: 'Ext.tree.Panel',
xtype: 'projectsTree',
title: 'Projects',
hideHeaders: true,
root: {
text: "Projekte"
}
});
It try to get the root node from my tree view in the controller but I get the error that getRootNode() is not a valid function in my controller. Can anybody tell me why I get this error? My target is to add new children to this root node from an ajax request.
Thanks
The methods Ext generates for each string in the views array return constructors that can be used to create the respective views. That seems bizarre, but that's how it is.
If you want to access the actual view component, you'll need to create a ref for it. Your init method should not assume that the view exists yet. It's very likely that it won't since the controller's init method is called before the application's launch method which is probably where all the views are getting added to the page.
You want to put your logic in the controller's onLaunch template method which is called after the application has been launched and your view has been added.
Ext.define('PM.controller.Projects', {
extend: 'Ext.app.Controller',
refs: [{
ref: 'projectsTreeView',
selector: 'projectsTree'
}],
init: function() {
// It's safe to add selectors for views that don't exist yet.
this.control(/*...*/)
},
onLaunch: function(config) {
var tree = this.getProjectsTreeView();
var rootNode = tree.getRootNode();
console.log(rootNode);
}
});
If this doesn't work, that means you aren't actually adding your view anywhere. One place you could add it is in the application's launch method. Something has to add the treeview.
Ext.application({
// ...
views: ['projects.Tree']
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [new this.getProjectsTreeView()]
});
}
});
So the chronology of events is this:
Application#constructor
Controller#constructor
Controller#init (can't assume the view exists)
Application#onBeforeLaunch
Application#launch (view is now added)
Controller#onLaunch (do something with the view that is now available)
Also, your view alias may need to be 'widget.projectsTree' not just 'projectsTree'.

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()

Extjs4 and binding functions to events in GridPanel

I'm new to Extjs library and I cannot figure out how to add listener to some events in GridPanel. As I'm filling the grid asynchronously I want my function to be executed when we add new element to grid panel.
I found (I think) correct event:
added( Ext.Component this, Ext.container.Container container, Number pos )
but I cannot find a correct place to put the listener as this function is executed only once on the page load:
Ext.define('MyApp.NewsGrid', {
extend: 'Ext.grid.GridPanel',
alias: 'widget.newsgrid',
initComponent: function() {
Ext.apply(this, {
title: 'News',
store: newsStore,
viewConfig: {
plugins: [{
pluginId: 'preview',
ptype: 'preview',
bodyField: 'testo',
expanded: false
}],
listeners: {
add: function() {
alert("add executed");
},
added: function() {
alert("added executed");
}
}
},
....
The problem is that there are different ways to add listeners (inside and outside viewConfig hash, inside and outside component definition etc...) and I cannot figure out one that works in this case. What makes it even more frustrating is that there are many places in the internet with documentation for version 3 or even without specifying the version.
You should listen the add event of Store:
initComponent: function() {
// somewhere inside initComponent...
this.getStore().on("add", function(store, records) {
alert(records.length + " records added");
}, this);
}

Resources