简体   繁体   中英

How to read a nested json file using ExtJS 4

I've the following JSON file (stored as "jobInfo.json"):

{
  "job": {
     "id": 1,
     "name": "Job 1",
     "description": "bla bla bla",
     "locations": {
        "type": "FeatureCollection",
        "features": [{
           "id": 1,
           "type": "Feature",
           "geometry": {
              "type": "Point",
              "coordinates": [9.523853, 47.671412]
           },
           "properties": {
              "name": "poi 1"
           }
        }, {
           "id": 2,
           "type": "Feature",
           "geometry": {
              "type": "Point",
              "coordinates": [9.484092, 47.650899]  
           },
           "properties": {
              "name": "poi 2"
           }
        }]
     }
  }
}

I need to read this file from ExtJS 4. In a first step , it gets the job properties 'name', and 'description'. I've tried to use the following model:

Ext.define('VZ.model.Job', {
   extend: 'Ext.data.Model',
   alias: 'widget.jobmodel',
   idProperty: 'id',
   fields: [
      {
          name: 'id',
          type: 'integer'
      }, {
          name: 'name',
          type: 'string'
      }, {
          name: 'description',
          type: 'string'                            
      },
     'locations'
   ]
});

In the a controller I do the following:

var jobfile = "data/jobs/jobInfo.json"
var jobInfo = Ext.create('Ext.data.Store', {
        model: 'VZ.model.Job',
        proxy: {
           type: 'ajax',
           url: jobfile,
           reader: {
              type: 'json'
              root: 'job'
           }
        }
});

But this doesn't work.

In a second step I need to access the property 'features' as root.

As I had the json file ("data/jobs/job.json") with only features ...

{
"type": "FeatureCollection",
"features": [{
    "id": 472
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [9.523853, 47.671412]
    },
    "properties": {
        "name": "Flughafen"
    },
}, {
    "id": 458
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": [9.484092, 47.650899]
    },
    "properties": {
        "name": "Hafen"
    },

}]
}

... the following code worked well:

var jobfile = "data/jobs/job.json"
var jobStore = Ext.create('GeoExt.data.FeatureStore', {
    fields: [
        {name: 'name', type: 'string'}
    ],
    autoLoad: true,
    proxy: Ext.create('GeoExt.data.proxy.Protocol', {
        reader: Ext.create('GeoExt.data.reader.Feature', {**root: 'features'**}),
        protocol: new OpenLayers.Protocol.HTTP({
            url: jobfile
            format: new OpenLayers.Format.GeoJSON({
                internalProjection: new OpenLayers.Projection('EPSG:900913'),
                externalProjection: new OpenLayers.Projection('EPSG:4326')
            })
        })
    })
});

So, I can use info as layer on openlayers.

But now, when I use "jobInfo.json", I try to use 'job.locations.features' as root. But I get an error:

Uncaught TypeError: Cannot read property 'locations' of undefined

Can somebody help me. What am I doing wrong?

Thank you in advance

There are lots of issues with your code

- url should be passed to proxy instead of store
- make use of associations when reading nested data

For your first issue below the code

Working example: https://fiddle.sencha.com/#fiddle/uno

Ext.define('VZ.model.Feature', {
   extend: 'Ext.data.Model',
   alias: 'widget.featuremodel',
   idProperty: 'id',
   fields: [
      {
          name: 'id',
          type: 'integer'
      }, {
          name: 'type',
          type: 'string'
      }, {
          name: 'geometry_type',
          type: 'string',
          mapping: 'geometry.type'
      }
   ]
});

Ext.define('VZ.model.Job', {
   extend: 'Ext.data.Model',
   alias: 'widget.jobmodel',
   idProperty: 'id',
   fields: [
      {
          name: 'id',
          type: 'integer'
      }, {
          name: 'name',
          type: 'string'
      }, {
          name: 'description',
          type: 'string'                            
      }
   ],
    associations: [{
        type: 'hasMany',
        model: 'VZ.model.Feature',
        name: 'features',
        associationKey: 'locations.features' // read child data from nested.child_groups
    }]
});


Ext.application({
    name : 'Fiddle',

    launch : function() {
        //Ext.Msg.alert('Fiddle', 'Welcome to Sencha Fiddle!');

        Ext.create('Ext.data.Store', {
            storeId: 'check',
            model: 'VZ.model.Job',
            proxy: {
                type: 'ajax',
                reader: {
                    type: 'json',
                    root: 'job'
                },
                url: 'jobinfo.json'
            },
            autoLoad: true
        });

        // give some time to load data
        setTimeout(function() {
            var store = Ext.getStore('check');
            var rec = store.getAt(0);
            var astRec = rec.featuresStore.getAt(0);

            alert('Job Record ' + rec.get('description'));
            alert('Feature Record ' + astRec.get('geometry_type'));
        }, 1000);

    }
});

Json file also needs one change

{
  "job": [{
     "id": 1,
     "name": "Job 1",
     "description": "bla bla bla",
     "locations": {
        "type": "FeatureCollection",
        "features": [{
           "id": 1,
           "type": "Feature",
           "geometry": {
              "type": "Point",
              "coordinates": [9.523853, 47.671412]
           },
           "properties": {
              "name": "poi 1"
           }
        }, {
           "id": 2,
           "type": "Feature",
           "geometry": {
              "type": "Point",
              "coordinates": [9.484092, 47.650899]  
           },
           "properties": {
              "name": "poi 2"
           }
        }]
     }
  }]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM