PDA

View Full Version : load nested rows in model



nahun
23 Aug 2011, 9:00 PM
I've got nested rows due to the way an API sends back JSON, I can't change the way it replies.

The problem is the model isn't loading it correctly and I can't use the data. Below is example JSON:


{
"id":"list",
"jsonrpc":"2.0",
"result": [
[
[
{
"id":"1",
"length":"60000000",
"connections":"0",
"dir":"/home1"
}
]
],
[
[
{
"id":"2",
"length":"50000000",
"connections":"0",
"dir":"/home2"
}
]
]
]
}


The "result" field would be the root for the reader, but I don't know how to create the model to read the fields or if I need to use hasMany somehow. I can see the store has 2 items, but nothing in them.

Thanks

skirtle
23 Aug 2011, 10:58 PM
If the config option record (http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Json-cfg-record) behaved the same way as root this would be easy, you'd just set record: '[0][0]'. But it doesn't.

One way is to do a little overriding:


reader: {
root: 'result',
type: 'json',
extractData: function(root) {
var data = [], length = root.length, i = 0;

for (; i < length; i++) {
data[i] = root[i][0][0];
}

return Ext.data.reader.Reader.prototype.extractData.call(this, data);
}
}

nahun
24 Aug 2011, 4:06 PM
This is working great, thanks!

The only issue I have is if an entry is empty. The extractData function always fills in the data array with that undefined entry no matter what I do. Here is example JSON


{
"id":"list",
"jsonrpc":"2.0",
"result": [
[
[ ]
],
[
[
{
"id":"1",
"length":"60000000",
"connections":"0",
"dir":"/home1"
}
]
]
}


And a modified version of that function. Mostly the if statement testing if root[i][0] length is > 0 is important. But the console.log shows var data already has the data in it and the model complains about the field being undefined. If the empty entry is last, this doesn't happen though.


reader: {
type: 'json',
root: 'result',
extractData: function(root) {
var data = new Array();
console.log(data);
var length = root.length, i = 0;
for (; i < length; i++) {
if(root[i][0].length > 0) {
data[i] = data[i][0][0];
}
}

return Ext.data.reader.Reader.prototype.extractData.call(this, data);

}
}



I've tried using root[i][0][0] !== undefined instead of testing the length, but no difference.

nahun
24 Aug 2011, 4:32 PM
So I got it to work by looping through data afterwards and splicing out the undefined field. Seems like a hokey way to do it though.


reader: {
type: 'json',
root: 'result',
extractData: function(root) {
var data = [], length = root.length, i = 0;
for (; i < length; i++) {
data[i] = root[i][0][0];
}
for (i = 0; i < length; i++) {
if(data[i] === undefined) {
data.splice(i,1);
}
}
return Ext.data.reader.Reader.prototype.extractData.call(this, data);
}
}

skirtle
24 Aug 2011, 5:12 PM
Try this:


reader: {
type: 'json',
root: 'result',
extractData: function(root) {
var data = [], length = root.length, i = 0;

for (; i < length; i++) {
if (root[i][0].length) {
data.push(root[i][0][0]);
}
}

return Ext.data.reader.Reader.prototype.extractData.call(this, data);
}
}

nahun
24 Aug 2011, 5:15 PM
Works perfectly, thanks skirtle!