I have a GridPanel that must have its store model AND column model created dynamically, after a DB SP returns the columns of the table.
My question is how can I pass
Ext provides some support for that. You can send the model configuration by adding a metaData property to the server response. You can configure the name of the property with the metaProperty option.
The documentation doesn't make it obvious, but you can reconfigure the fields of the model this way. Here's the kind of response that would do that:
{
data: [...]
,metaData: {
// This will be recognized and processed automatically
// by the proxy
fields: [
{name: "id", type: "int"},
{name: "myField", type: "string"},
...
]
// This one is for our own usage, see bellow
,columns: [
{dataIndex: "id", text: "ID},
{dataIndex: "myField", text: "My field"},
...
]
}
}
As noted in the doc, when the data model changes, you'll want to update your components as well. Sencha has provided the metachange for that. Notice that, while documented in the proxy, this event will be relayed by the store.
Finally, to update the grid's column model, you have the reconfigure method. For example, you could modify your grid class in the following way to make it reconfigure itself automatically from the server response:
Ext.define('Base.GridPanel', {
extend: 'Ext.grid.Panel'
// ...
// You can add your listener in initComponent, if you're
// reluctant to extend a method docuemented as private...
,bindStore: function(store) {
// unbind previously bind store, if any
var previous = this.getStore();
if (previous) {
previous.un('metachange', this.onMetaChange, this);
}
// bind to the meta change event
this.getStore().on('metachange', this.onMetaChange, this);
this.callParent(arguments);
}
,onMetaChange: function(store, meta) {
var columns = meta.columns;
if (columns) {
this.reconfigure(null, columns);
}
}
});
Update
The onMetaChange
method is called when the metachange
event is fired, because I have registered it as a listener with this line:
this.getStore().on('metachange', this.onMetaChange, this);
The event itself is fired when the proxy detects some meta data in the server response. Concretely, that happens when a metaData
property (or whatever name you may have configured as the metaProperty
of the proxy) exists in the server response.
The listener is effectively passed the raw metaData
object, that is present in the response, as its second argument (named meta
in my example). So your server can put any information you need in it (e.g. new field labels, tooltip texts, etc.).
bindStore
is a method that is already present in GridPanel
. Here I override it because I need a place to register my event listener on the store. As its name suggests, this method is called to bind a store to the component. It can be the initial store, or a new one. That's one I've preferred to override this method instead of initComponent
. In case the store is changed later in the component life, my custom listener will be unbound from the old store and attached to the new one.
The arguments keyword is an idiosyncrasy of Javascript. It represents all the arguments that have been passed to a function. callParent is a sweety provided by Ext to call the parent method; it takes an array as the arguments that will be passed to the parent. So this.callParent(arguments)
calls the parent method without having to know what were precisely all the arguments of the overridden method. That's easier, and that's also more resilient to future changes, if the arguments of the method were to change...
I'd be glad to point you to a comprehensive guide about overriding in Ext... Unfortunately I couldn't find one with a quick search :-/