Extend a grid with listeners - extjs

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

Related

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

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.

EXTJS 5 - ViewModel getting Store returns null value

Im currently having an issue regarding stores declared in ViewModel, using Extjs5's MVVM feature.
Simple Use case:
ViewModel:
Ext.define('App.view.view1.View1Model', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.view1',`
data: {
},
stores:{
Company:{
model: 'UM.model.CompanyData',
type: 'CompanyData', //Store name
autoLoad: true
}
}
}];
While code below is my viewController:
ViewController:
Ext.define('App.view.view1.View1Controller', {
extend: 'Ext.app.ViewController',
alias: 'controller.view1',
onloadnewdata: function(event, item,store){
var vm= this.getViewModel();
var store=vm.getStore('Company');
console.log(store);
}
});
On firing some event with "onloadnewdata" function based on the console store is null.
All I need to do is get the store declared on the ViewModel. Please help me which part is wrong or is this a bug?
Appreciate if you share some ideas or other approach. Thanks.
I think you need to modify the code something like below. In order to get the reference to the ViewModel first you need to get the reference to View.
Ext.define('App.view.view1.View1Controller', {
extend: 'Ext.app.ViewController',
alias: 'controller.view1',
onloadnewdata: function(event, item,store){
var store = this.getView().getViewModel().getStore('Company');
console.log(store);
}
});
You can refer this sencha fiddle https://fiddle.sencha.com/#fiddle/fpb. Just check this following controller TestApp.view.grid.GenericGridController . Hope it helps!

Sencha Touch access method in parent view

I'm trying to access a function from a component initialize. New to Sencha Touch/Ext.js, so not sure how scope works. I have 'spin' listeners in the 'control' which seem to work well, when incremented.
Simplified Code:
Ext.define('App.view.CreateChallenge', {
extend: 'Ext.Container',
fullscreen: true,
xtype: 'CreateChallenge',
config:{
items[
xtype: 'spinnerfield',
itemId: 'mySpin',
initialize:function(){
App.view.Challenge.doThis();
}
],
control:{
'#mySpin' : {
spin: 'doThis'
}
}
},
doThis:function(){
console.log('dooing this');
}
});
Thanks,
Steve
First of all, you should not override initialize method in the config block, the proper place for that is in Ext.define.
Then, in initialize, you can call App.view.CreateChallenge.doThis(). But it just an ordinary function, its scope is the global window object, so you don't have access to the object of App.view.CreateChallenge.
To find a container reference from its children, you can use Ext.Component.up(). In your case, it will look like:
initialize: function() {
…
this.up('CreateChallenge').doThis(); // find container by xtype then call its method
}
We are not there yet! If you try, you are going to get an undefined from this.up(…). This is because the container isn't finished constructing while its children are initializing. So, if you need a reference of the container in the initialize method, you need to wait until the container is ready, such as the painted event.
Then, you will end up something looks like:
initialize: function() {
…
this.on('painted', function () {
this.up('CreateChallenge').doThis(); // find container by xtype then call its method
}, this);
}
I would simply use
VIEW/This .getParent()

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

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