PDA

View Full Version : Dynamically Create model/store for Grid from json data



jeremym
24 Jan 2012, 1:38 PM
I'm new to Ext Js and have been getting my feet wet by writing some very basic prototypes of the sorts of UI components that I plan to be developing with going forward. I started with a basic chart and graph using pre-defined models and have moved on to try to create a Grid that uses a dynamic model. In the long run I expect to need to display a table (grid) on screen based on a json representation of columns/values that comes back from a webserver. In the short term I'm using a local file to load the data. My goal is that the grid will dynamically display the columns without needing those columns to be predefined... so if the data coming back is [{'x':1, 'y':2}, {'x':2, 'y':5}, {'x':3, 'y':9}] I want the chart to display X and Y columns, but if it comes back as [{'x':1, 'y':2, 'z':4}, {'x':2, 'y':7, 'z':1}, {'x':3, 'y':3, 'z':8}] I want all three columns displayed. If the data I'm anticipating in the long run only had 2-3 columns I would define specific models for them, but in production I may be looking at 40-50 different values coming back from the server in various mix/match combinations. I could define a model with all possible metrics and then hide the ones that don't get populated, but I'd like to consider that a fallback case for now. After googling around for similar attempts (and finding several that were close but incompletely) I've tried a couple of methods of implementing this... at the moment I have the view class initComponent function making an ajax call to read the data, parsing the keys into an array, then defining the model and store, reloading the store, reconfiguring the grid (may not be neccessary, I'm not sure), and calling the parent constructor. The this.callParent(arguments) method is failing with a firebug error of:

me.headerCt is undefined
http://localhost:8080/proto/extjs/ext-all-debug.js
Line 78081


I tried removing the this.callParent(..) call and instead I get a "body is undefined" error when I navigate to the tab where this particular view is being displayed. I suspect I may need to do more around defining the headers (though I did try setting this.columns manually instead of off of the results object without success)... Since I've run into a roadblock with this and am the first developer in my group to start experimenting with ext js, I was hoping someone here could point me in the right direction. I've included relevant snippets of my code below. Thanks!

The view code:

Ext.define('Proto.view.tables.DynamicBaseTable', {
extend: 'Ext.grid.Panel',
alias: 'widget.dynamicbasetable',
title : 'Dynamic table',

initComponent: function() {
Ext.Ajax.request({
url: 'data/dynamiccharts.json',
success: function(response){
var tableFields = [];
var decodedObj = Ext.decode(response.responseText, false);
var columnsFromData = decodedObj.results;

Ext.each(columnsFromData, function(column){
for(var key in column){
if(contains(tableFields, key) == false){
tableFields.push(key);
}
}
});

Ext.define('Proto.model.DynamicColumnsModel', {
extend: 'Ext.data.Model',
fields: tableFields
});

this.store = Ext.create('Ext.data.Store', {
model: 'Proto.model.DynamicColumnsModel',
autoLoad: true,
proxy: {
type: 'ajax',
url : 'data/dynamiccharts.json',
reader : {
type: 'json',
root: 'results'
}
}
});

this.store.load();
this.columns = columnsFromData;
}
});
this.reconfigure(this.store);
this.callParent(arguments);
}

});

and my small json file:


{
'success': true,
'results': [
{'x-value': 1, 'y-value': 2, 'host': 'host1'},
{'x-value': 2, 'y-value': 4, 'host': 'host1'},
{'x-value': 3, 'y-value': 6, 'host': 'host1'},
{'x-value': 4, 'y-value': 8, 'host': 'host3'},
{'x-value': 5, 'y-value': 3, 'host': 'host2'},
{'x-value': 6, 'y-value': 6, 'host': 'host2'},
{'x-value': 7, 'y-value': 9, 'host': 'host2'}
]
}

jeremym
24 Jan 2012, 3:52 PM
I'm thinking I may have a scoping issue... inside the Ajax.request success method the "this" appears to be for the parent window rather than for my DynamicBaseTable ... so when I set the store there it's not in the proper scope... but I'm not 100% sure why yet... Is my best guess so far....