PDA

View Full Version : Recreating Grid With Different model and Fails or BUG?



newbie.scott
5 Oct 2011, 9:59 AM
Hello All,

I am trying to create a grid table dynamically to display different model data, depending on the user query. Initially I was using 'destroy/close' method to kill the existing grid and recreating a brand new grid with different model, store. However it works fine for first '2' attempts, then starts displaying error messages.

Then I modified code to have only a single grid, but used 'reconfigure' method to change model and store dynamically. Again it works for first '2' attempts, then fails when I tried for 3rd time.

Error: at Proxy class
Uncaught TypeError: Cannot read property 'isReader' of undefined
Uncaught TypeError: Cannot call method 'replace' of undefined

I have attached the code and screen shot.

Is this a Bug OR am doing it wrong.
Thanks for your help in advance.

Here is the sample code, I hard coded for testing purpose :


/*Hardcoded Grid Configuration 1: Model,Store,Columns*/
Ext.define('Model1', {
extend : 'Ext.data.Model',
fields : [ 'name', 'email', 'phone' ]
});
var store1 = Ext.create('Ext.data.Store', {
model : 'Model1',
autoLoad : true,
pageSize : 4,
proxy : {
type : 'ajax',
url : 'data/users.json',
reader : {
type : 'json',
root : 'users',
totalProperty : 'total'
}
}
});
var columns1 = [ {
text : 'Name',
width : 100,
dataIndex : 'name'
}, {
text : 'Email Address',
width : 150,
dataIndex : 'email'
}, {
text : 'Phone Number',
flex : 1,
dataIndex : 'phone'
} ];


/*Hardcoded Grid Configuration 2: Model,Store,Columns*/
Ext.define('Model2', {
extend : 'Ext.data.Model',
fields : [ 'title', 'story' ]
});
var store2 = Ext.create('Ext.data.Store', {
model : 'Model2',
autoLoad : true,
pageSize : 4,
proxy : {
type : 'ajax',
url : 'data/story.json',
reader : {
type : 'json',
root : 'stories',
totalProperty : 'total'
}
}
});
var columns2 = [ {
text : 'title',
width : 100,
dataIndex : 'title'
}, {
text : 'story',
flex : 1,
dataIndex : 'story'
} ];



if ((extTable != undefined) || (extTable != null)) {
console.log('extTable exist, reconfiguring');
extTable.reconfigure(store2, columns2);
} else {
extTable = Ext.create('Ext.grid.Panel', {
renderTo : Ext.getBody(),
store : store1,
width : 400,
height : 200,
title : 'title',
columns : columns1
});
}


Here is the Error Screenshot
28538

Cheers
S

skirtle
5 Oct 2011, 4:04 PM
Tried your code and it works fine for me against 4.0.2 and 4.0.6.

That said, you haven't made it clear exactly which bits of the code should go inside the button handler and which bits go outside the handler. This could make a huge difference to whether or not it works. Are you able to post a complete example?

One observation from the stacktrace. I don't see a call to reconfigure() in that stacktrace, it appears to be failed trying to do an Ext.create(). Judging by the methods mentioned at the top it seems to be failing creating the proxy, which suggests it is an issue creating the store.

One thought that occurs. Are your Ext.define() calls inside or outside of the button handler? You must not try to define a class twice, all sorts of crazy things happen if you do.

joseph09
6 Oct 2011, 9:13 PM
I was having a very similar issue where I could load a store twice but on the third time I got:

Uncaught TypeError: Cannot read property 'isReader' of undefined

The issue was only happening in chrome.

skirtle's answer was spot on. The problem was that I was defining a model multiple times. Once I moved where the model was defined so that it was only defined once the problem was solved.

Thanks skirtle for the time saver!

newbie.scott
7 Oct 2011, 4:50 AM
Thanks very much skirtle.

I was defining classes several times in my test code, that was the problem, after moving class creations/definitions out of button handler method, am not seeing anymore errors. Thanks for saving me once again.

However this time am not able to see data loading into the table, please find the test example below. Can you please tell me what am doing wrong. All i am trying to achieve is create one global instance/skeleton of model, proxy, store and table; then reuse them dynamically by reconfiguring model fileds, proxy URLs changes, store,etc. To further complicate, in my production code I am using closures, my own namespaces and custom handlers for proxy:read,write methods,etc. I didn't find any example of creating dynamic grid on web, or may have missed it. But before I get into that first I need to see if I can make a dynamic grid :( with simple test code. Sorry for the late reply, I was trying to get this working without seeking any help, but no luck.

Here is the test code:



<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Table Component</title>
<script type="text/javascript" src="js/ext-all-debug.js"></script>
<link rel="stylesheet" type="text/css" media="screen, projection"
href="css/ext-all.css" />
</head>




<script>
/*Create initial skeleton classes which dynamically reconfigured later to display different data*/


var modelId = 'myModel';
var myFields;

Ext.regModel(modelId, {
extend : 'Ext.data.Model'
});
var myProxy = Ext.create('Ext.data.proxy.Ajax', {
reader : {
type : 'json',
}
});

var myStore = Ext.create('Ext.data.Store', {
model : Ext.ModelManager.getModel(modelId),
proxy : myProxy,
autoLoad : false,
autoDestroy : false,
pageSize : 4
});




var tableColumns;
var extTable ;

/*create grid button handler*/
function createGrid() {

if ((extTable != undefined) || (extTable != null)) {
console.log('extTable exist, reconfiguring');

/*reconfigure Ajax proxy*/
myProxy.url = 'data/story.json';
myProxy.getReader().root = 'stories';

/* reconfigure model with new fields*/
myFields = [ 'title', 'story' ];
Ext.ModelManager.getModel(modelId).fields = myFields;

/* reconfigure store with mode and proxy*/
myStore.model = Ext.ModelManager.getModel(modelId);
myStore.setProxy(myProxy);

tableColumns = [ {
text : 'title',
width : 150,
dataIndex : 'title'
}, {
text : 'story',
flex : 1,
dataIndex : 'story'
} ];

extTable.reconfigure(myStore, tableColumns);
extTable.getStore().load();
} else {
/*reconfigure Ajax proxy*/
myProxy.url = 'data/users.json';
myProxy.getReader().root = 'users';

/* reconfigure model with new fields*/
myFields = [ 'name', 'email', 'phone' ];
Ext.ModelManager.getModel(modelId).fields = myFields;

/* reconfigure store with mode and proxy*/
myStore.model = Ext.ModelManager.getModel(modelId);
myStore.setProxy(myProxy);

tableColumns = [ {
text : 'Name',
width : 100,
dataIndex : 'name'
}, {
text : 'Email Address',
width : 150,
dataIndex : 'email'
}, {
text : 'Phone Number',
flex : 1,
dataIndex : 'phone'
} ];

extTable = Ext.create('Ext.grid.Panel', {
renderTo : Ext.getBody(),
store : myStore,
width : 400,
height : 200,
title : 'title',
columns : tableColumns
});
extTable.getStore().load();
}




}


</script>
<body>
<button type="button" onclick="createGrid();">create grid</button>
</body>
</html>





users.json:




{
"success": true,
"total": 12,
"users": [
{ "name": "Lisa", "email": "[email protected]", "phone": "555-111-1224" },
{ "name": "Bart", "email": "[email protected]", "phone": "555-222-1234" },
{ "name": "Homer", "email": "[email protected]", "phone": "555-222-1244" },
{ "name": "Marge", "email": "[email protected]", "phone": "555-222-1254" }
]
}





story.json


{
"success": true,
"total": 12,
"stories": [
{ "title": "123", "story": "abc" },
{ "title": "asd", "story": "rty" },
]
}




Screen shot
28569
Thanks once again for looking into this

Cheers
S

newbie.scott
7 Oct 2011, 4:59 AM
Thanks joseph09 (http://www.sencha.com/forum/member.php?15911-joseph09) for your input :)