PDA

View Full Version : How to define models to fit this JSON?



bjnelson62
26 Sep 2012, 1:34 PM
I am new to ExtJs, but making progress.

I'm writing a client webapp that talks to a server, which returns data that is hierarchical in nature. Hence, I've chosen a TreePanel to represent this data.

As I learned in a previous post, the root nodes of my tree are static, but the children below come from the server. This is working, up to a point.

Now I've reached the point where the model I was using before for the data is insufficient, as the server is returning a response that doesn't map to this model. Here's an example of the JSON returned by the server:



{
"nodes": [
{
"host-names": [
"machine1"
],
"ip-addresses": [
"192.168.1.33",
"127.0.0.1",
],
"links": [
{
"rel": "self",
"href": "https://localhost:8443/product1/v1/nodes/34/ (https://localhost:8443/vfabric/v1/nodes/34/)",
"type": "application/json; charset=utf-8"
}
]
},
{
"host-names": [
"machine2"
],
"ip-addresses": [
"192.168.1.54",
"127.0.0.1"
],
"links": [
{
"rel": "self",
"href": "https://localhost:8443/product1/v1/nodes/27/ (https://localhost:8443/vfabric/v1/nodes/27/)",
"type": "application/json; charset=utf-8"
}
]
}
],
"links": [
{
"rel": "self",
"href": "https://localhost:8443/product1/v1/nodes/ (https://localhost:8443/vfabric/v1/nodes/)",
"type": "application/json; charset=utf-8"
},
{
"rel": "security",
"href": "https://localhost:8443/product1/v1/security/2/ (https://localhost:8443/vfabric/v1/security/2/)",
"type": "application/json; charset=utf-8"
}
]
}


Here are the two classes I've defined to try to model this:



Ext.define('MyApp.model.NodesModel', {
extend: 'Ext.data.Model',
requires: [
'MyApp.model.LinksModel'
],
// The fields 'host-names' and 'ip-addresses' are both arrays.
fields: [
{name: 'text', mapping: 'host-names', type: 'auto'},
{name: 'id', mapping: 'ip-addresses', type: 'auto'}
],
hasMany: {
model: 'LinksModel', name: 'links', getterName: 'getLinks'
},
proxy: {
type: 'ajax',
noCache: false,
url: 'https://localhost:8443/',
directionparam: undefined,
extraParams: undefined,
filterParam: undefined,
groupParam: undefined,
limitParam: undefined,
pageParam: undefined,
sortParam: undefined,
startParam: undefined,
reader: {
type: 'json',
root: 'nodes'
}
}
});

Ext.define('MyApp.model.LinksModel', {
extend: 'Ext.data.Model',
fields: [
{
name: 'text',
mapping: 'rel'
},
{
name: 'id',
mapping: 'href'
},
{
name: 'type'
}
],
belongsTo: 'NodesModel',
proxy: {
type: 'ajax',
noCache: false,
url: 'https://localhost:8443/',
directionparam: undefined,
extraParams: undefined,
filterParam: undefined,
groupParam: undefined,
limitParam: undefined,
pageParam: undefined,
sortParam: undefined,
startParam: undefined,
reader: {
type: 'json',
root: 'links'
}
}
});





The LinksModel I know works, because the first two layers of the tree use it and the tree is working fine there. I've defined my TreeStore to use the LinksModel by default.

It may be the problem lies with how I'm using these models, and not the model definitions, but I figured to start with the basics first. [Aside: I'm listening to the 'beforeitemexpand' event in the tree, and swapping in the NodesModel into the TreeStore in that function when appropriate.]

Alternatively, how could I debug this to see how the framework is looking at the returned JSON and parsing it (I can see in the debugger that the expected JSON *is* being returned)?

Thank you,


Brian

bjnelson62
27 Sep 2012, 4:58 AM
I should have mentioned I'm not using a treepanel with columns, as I've read that has problems with reconfigure. It's just a plain tree.

At a high level, what are some ways or the best way of handling this situation, where different nodes in a tree use different models? Here are the 3 ways I've come across in my travels:

1. Brute force, define a different model and store for each different response from the server. I tried this, but couldn't get it to work.

2. Use one store, but different models. This is what I'm doing now, except it doesn't fully work. The JSON reader parses out the Links info, but not the Nodes info. It may be I haven't defined my model correctly, hence this post.

3. I read where you could reconfigure the fields of your model on the fly. That seems less attractive to me because even if it works, it'll be hard to understand and maintain by others.

Thank you,

Brian

bjnelson62
1 Oct 2012, 11:57 AM
Looking in the debugger, it seems like my code is correct. The problem seems to be in the tree.

After some searching, I found this post:

http://www.sencha.com/forum/showthread.php?130060-Ext-4-trees-a-step-forward&p=590905&viewfull=1#post590905

Which essentially says there's a 1:1 relationship between stores and models. In other words, you can't have multiple models in a single tree.

In that thread, a Sencha developer mentioned that there are workarounds. Could someone post what some of those workarounds are?

One that occurs to me is you might be able to define a super-model that encompasses all your models; then you'd need to write special code that would figure out which model you got back from the server, so you could figure out what fields to use for 'text' and 'id'.

However, that's not the case with our server. The first two models I defined have that relationship, but down the road I can see other models that will be unrelated to one of the other models.

This seems like a pretty big hole; I found other comments that state that this limitation essentially breaks RESTful servers, which is what we have (and I'm sure lots of other folks as well). If we can't find a way around this, we'll probably have to look at other options for our web UI.

Brian