Extjs parsing nested json in a template

Trying (unsuccessfully) to display data from a nested json.

JSON might look something like this:

{ "contacts": [ { "id": "1", "client_id": "135468714603", "addresses": [ { "id": "1", "contact_id": "1", "address_id": "16", "address": { "0": { "id": "16", "address": "123 Some Rd", "address2": "", "city": "Toen", "state": "VS", "zip_code": "11111", "country": "USA" } } }, { "id": "6", "contact_id": "1", "address_id": "26", "address": { "0": { "id": "26", "address": "1 Other Road", "address2": "", "city": "Twn", "state": "BD", "zip_code": "11112", "country": "USA" } } } ] }, { "id": "10", "client_id": null, "addresses": [ { "id": "8", "contact_id": "10", "address_id": "28", "address": { "0": { "id": "28", "address": "54 Road", "address2": "", "city": "TWND", "state": "TT", "zip_code": "11113", "country": "USA" } } }, { "id": "9", "contact_id": "10", "address_id": "29", "is_mailing_address": "0", "is_primary_address": "0", "display_priority": "0", "address": { "0": { "id": "29", "address": "6 Road", "address2": "", "city": "TOEOEOWN", "state": "PY", "zip_code": "11116", "country": "USA" } } }, { "id": "10", "contact_id": "10", "address_id": "30", "address": { "0": { "id": "30", "address": "PO Box 9", "address2": "", "city": "TOYN", "state": "GF", "zip_code": "11118", "country": "USA" } } } ] }, { "id": "11", "client_id": null, "contact_id": "11", "addresses": [ { "id": "11", "contact_id": "11", "address_id": "33", "is_mailing_address": "0", "is_primary_address": "0", "display_priority": "0", "address": { "0": { "id": "33", "address": "4 Street", "address2": "", "city": "TEOIN", "state": "TG", "zip_code": "11119", "country": "USA" } } } ] } ] } 

I tried to match the model fields with what I needed (for example, contact model> address field> mapping: addresses), but this does not work, because I will need to map the addresses [0] .address [0] to get the data that obviously discard other addresses.

I also tried playing with associations, but these seem to be separate models and stores. The idea here is not to make a separate request for contacts and then their addresses.

I also tried digging into json right in the template (which seemed the easiest way), for example. {addresses.address.city} which does not work.

The idea is simple: take some json and show different parts of json in different parts of the application.

The experience was terrible.

Can someone explain how to map these nested json elements so that they are accessible from the template?

Template:

 { xtype: 'container', flex: 1, id: 'mainPanel', items: [ { xtype: 'dataview', hidden: false, id: 'clientsContacts', minHeight: 200, itemSelector: 'div', itemTpl: [ '{id} | {last_name} | {first_name} | {relationship} | {addresses}' ], store: 'Contacts' } ] } 

Save:

 Ext.define('MyApp.store.Contacts', { extend: 'Ext.data.Store', requires: [ 'MyApp.model.Contacts' ], constructor: function(cfg) { var me = this; cfg = cfg || {}; me.callParent([Ext.apply({ autoLoad: false, storeId: 'Contacts', model: 'MyApp.model.Contacts', proxy: { type: 'ajax', extraParams: { id: '', format: 'json' }, url: '/api/contacts/', //the json reader: { type: 'json', root: 'contacts' } }, listeners: { load: { //fn: me.onJsonstoreLoad, //scope: me } } }, cfg)]); }, }); 

Model:

Ext.define ('MyApp.model.Contacts', {expand: 'Ext.data.Model',

  uses: [ //'MyApp.model.Client', //'MyApp.model.contactAddressModel' ], fields: [ { name: 'client_id' }, { name: 'id' }, { name: 'addresses', mapping: 'addresses'//doesn't work //mapping: 'addresses[0].address[0]' //works, but only for the first address duh } ], }); 

Using extjs 4.1 through Sencha Architect.

Any help would be greatly appreciated.

Thanks.

+4
source share
2 answers

I think I have it (hope this is correct).

So, create a field for each nested data group that you need. Therefore, I have a contact model. This model has the following fields:

 id client_id addresses //mapped to addresses address //mapped to addresses.address 

then in the template:

 <br> <tpl for="addresses"> id: {id}<br> addy id: {address_id}<br> <tpl for="address"> {city} {state}, {zip}<br> </tpl> </tpl> 

Here is what it looks like:

View

 Ext.define('MyApp.view.MyView', { extend: 'Ext.view.View', height: 250, width: 400, itemSelector: 'div', store: 'MyJsonStore', initComponent: function() { var me = this; Ext.applyIf(me, { itemTpl: [ '<br>', '<tpl for="addresses">', ' id: {id}<br>', ' addy id: {address_id}<br>', ' <b>', ' <tpl for="address">', ' {city} {state}, {zip}<br><br>', ' </tpl>', ' </b>', '', '</tpl>', '', '<hr>', '' ] }); me.callParent(arguments); } }); 

Score

 Ext.define('MyApp.store.MyJsonStore', { extend: 'Ext.data.Store', requires: [ 'MyApp.model.Contacts' ], constructor: function(cfg) { var me = this; cfg = cfg || {}; me.callParent([Ext.apply({ storeId: 'MyJsonStore', model: 'MyApp.model.Contacts', data: { contacts: [ { id: '1', client_id: '135468714603', addresses: [ { id: '1', contact_id: '1', address_id: '16', address: { '0': { id: '16', address: '123 Some Rd', address2: '', city: 'Toen', state: 'VS', zip_code: '11111', country: 'USA' } } }, { id: '6', contact_id: '1', address_id: '26', address: { id: '26', address: '1 Other Road', address2: '', city: 'Twn', state: 'BD', zip_code: '11112', country: 'USA' } } ] }, { id: '10', client_id: null, addresses: [ { id: '8', contact_id: '10', address_id: '28', address: { id: '28', address: '54 Road', address2: '', city: 'TWND', state: 'TT', zip_code: '11113', country: 'USA' } }, { id: '9', contact_id: '10', address_id: '29', is_mailing_address: '0', is_primary_address: '0', display_priority: '0', address: { id: '29', address: '6 Road', address2: '', city: 'TOEOEOWN', state: 'PY', zip_code: '11116', country: 'USA' } }, { id: '10', contact_id: '10', address_id: '30', address: { id: '30', address: 'PO Box 9', address2: '', city: 'TOYN', state: 'GF', zip_code: '11118', country: 'USA' } } ] }, { id: '11', client_id: null, contact_id: '11', addresses: [ { id: '11', contact_id: '11', address_id: '33', is_mailing_address: '0', is_primary_address: '0', display_priority: '0', address: { id: '33', address: '4 Street', address2: '', city: 'TEOIN', state: 'TG', zip_code: '11119', country: 'USA' } } ] } ] }, proxy: { type: 'memory', reader: { type: 'json', root: 'contacts' } } }, cfg)]); } }); 

Model

 Ext.define('MyApp.model.Contacts', { extend: 'Ext.data.Model', fields: [ { name: 'id' }, { name: 'client_id' }, { name: 'addresses', mapping: 'addresses' }, { name: 'address', mapping: 'address' } ] }); 
+4
source

I checked that the answer above really works, but for future people it should be noted that if you do not specify the name of the subfield, you do not need a second nested template. You can do this only the first time.

+1
source

All Articles