PDA

View Full Version : paging toolbar can't see grids store using this.ownerCt.getStore()



dirtdevil
30 Aug 2009, 12:44 PM
My paging bbar can't see the grids store when I try to tell it using this.ownerCt.getStore()...



{
xtype: 'grid',
//more grid stuff here
store: {
xtype: 'arraystore',
fields: [
{name: 'ID'},
{name: 'IPAddress'}
],
autoLoad: true,
remoteSort: true,
sortInfo: {
field: 'IPAddress',
direction: 'ASC'
},
url: 'postmembers.php',
baseParams: {
Action: 'IPREPORT'
}
},
bbar: {
xtype: 'paging',
pageSize: 25,
store: this.ownerCt.getStore(),
displayInfo: true,
displayMsg: 'Displaying topics {0} - {1} of {2}',
emptyMsg: "No topics to display",
items:[
'-', {
pressed: true,
enableToggle:true,
text: 'Show Preview',
cls: 'x-btn-text-icon details',
toggleHandler: function(btn, pressed){
}
}]
}


Logicly, based on it's position on the json object (paging xtype to grid) wouldn't it be able to get to the store using this.ownerCt.getStore() since the paging bar is nested in the grid?

mmusson
30 Aug 2009, 4:56 PM
No. The bbar is a config object that is created right when this declaration is processed. The grid does not exist yet. this.ownerCt.getStore() is being executed against whatever object contains the code you show.

You need to create the store ahead of time and then pass it into both config properties or delay creating the paging toolbar until the initComponent() of the grid.

dirtdevil
31 Aug 2009, 9:52 AM
But isn't that bad design to have the bbar build so soon when there are so many components that can go into it as xtypes?

mmusson
1 Sep 2009, 6:38 AM
No. There is no single correct way to create your components.

I am confused by the comment "...have the bbar built so soon...". The problem with your original code is not when the bbar is built, it is that you are referencing the grid store before the grid has been built.

Simplified, your config example was:

var config = {
xtype : 'grid',
store : { /* options */ },
bbar : {
xtype : 'paging',
store : this.ownerCt.getStore()
}
};

var p = Ext.ComponentMgr.create(config);
I separated the config from the create to emphasize the fact that your reference to this.ownerCt.getStore() doesn't work because the grid hasn't been created yet. This references something else in your code.

The easiest way to make this do what you want is to use the following:
{
xtype : 'grid',
store : {
storeId : 'my-grid-store',
/* other options */
},
bbar : {
xtype : 'paging',
store : 'my-grid-store'
}
}Why does this work? The grid component is created first and will create its store from the store config. The storeId property tells the Store to register itself with the StoreMgr. The paging toolbar config uses a storeId (string) instead of a config object causing the toolbar to do a lookup from the StoreMgr. The grid store is created before the grid creates its toolbars, so the toolbar is able to pickup the already existing grid store once it is created.

Does that make sense?

dirtdevil
1 Sep 2009, 1:43 PM
First off, thanks for the storeId thing, I read the docs on it and cleaned up a ton of code using it and it worked out great!

As for the ownerCt thing, that does make sense since PHP has that same logic since you can't access $this if the object isn't made yet and $this refers to the obj the class made, not the class. But what I don't get is the nesting logic on how it's made. Just so were on the same page, my belief is since I'm using xtypes, the grid is created first and any xtypes in it are created and any xtypes in that are created on down the chain of xtypes. With that logic, the grid is created first as well as the store since it's in the grid. When the paging bbar is created and it asks for the ownerCt.getStore(), at that point in execution, doesn't the grid as well as the store in it already exist?

mmusson
1 Sep 2009, 2:53 PM
You are right about the order of creation for the nested configs using xtypes but the missing piece is that a config object != object instance.

When you write code like var a = { b : 1 + 2 } the expression providing the value for b is executed immediately, so this really becomes var a = { b : 3 }. It would be different if the assignment was var a = { b : function () { return 1 + 2; } } Now the expression is not evaluated until a.b() is called.

The same is true for your config example. The reference to the store is evaluated when creating the instance of the config object. Following the same pattern above, you could override the initComponent() function of the paging toolbar and set the store reference there since this will not execute until after the store is created. Something like:


initComponent : function () {
this.store = this.ownerCt.store;
this.constructor.superclass.initComponent.apply(this, arguments);
}

dirtdevil
1 Sep 2009, 4:57 PM
ahhh, makes sense. thanks!