EXTJS4 - Why aren't my associated repositories loading child data?

So, I have a parent and child repository shown here:

Parent model

Ext.define('APP.model.Client', { extend: 'Ext.data.Model', requires: [ 'APP.model.Website', 'Ext.data.association.HasMany', 'Ext.data.association.BelongsTo'], fields: [{ name: 'id', type: 'string' }, { name: 'name', type: 'string' }, { name: 'slug', type: 'string' }, { name: 'active', type: 'boolean' }, { name: 'current', type: 'boolean' }], hasMany: { model: 'APP.model.Website', name: 'websites' } }); 

Baby model

 Ext.define('APP.model.Website', { extend: 'Ext.data.Model', fields: [{ name: 'id', type: 'string' }, { name: 'client_id', type: 'string' }, { name: 'sub_domain', type: 'string' }, { name: 'active', type: 'boolean' }], belongsTo: 'APP.model.Client' }); 

Using an AJAX call through the server, I load the Clients repository and it loads normally. But the Websites store does not fill up, and when I stop at the Clients store on.load function to see what it fills, the Client store is filled only with client data, but in raw for this store, I can see all the Websites data. This way it returns correctly, but my extjs are incorrect. Here are the shops:

Customer shop

 Ext.define('APP.store.Clients', { extend: 'Ext.data.Store', autoLoad: false, model: 'APP.model.Client', proxy: { type: 'ajax', url: '/client/list', reader: { type: 'json', root: 'items' } }, sorters: [{ property: 'name', direction: 'ASC' }] }); 

Website repository

 Ext.define('APP.store.Websites', { extend: 'Ext.data.Store', requires: ['Ext.ux.Msg'], autoLoad: false, model: 'APP.model.Website', proxy: { type: 'ajax', url: '/client/list', reader: { type: 'json', root: 'items' }, writer: { type: 'json' } }, sorters: [{ property: 'sub_domain', direction: 'ASC' }] }); 

My end result ... I would like to fill both stores so that I can click on the item, and when it loads something from the parent store, I can access the child store (there will be more when I find out this problem) to fill a couple of grid tabs.

What am I missing in my setup? I just downloaded extjs4 a couple of days ago, so I'm on 4.1.

+4
source share
2 answers

Put your proxies in your models if you have no good reason not to [1]

Ensure that require related model (s), either in the same file or earlier in the application

Use foreignKey if you want to load the relevant data as desired (i.e. with a subsequent network request).

Use associationKey if related data is loaded into the same (nested) response

Or just use both

Always name your relationship (otherwise the name will be strange if you use namespaces).

Always use the fully qualified model name for the model property in your relationship.

Work code:

model/Contact.js :

 Ext.define('Assoc.model.Contact', { extend:'Ext.data.Model', requires:[ 'Assoc.model.PhoneNumber' ], fields:[ 'name' /* automatically has an 'id' field */ ], hasMany:[ { model:'Assoc.model.PhoneNumber', /*use the fully-qualified name here*/ name:'phoneNumbers', foreignKey:'contact_id', associationKey:'phoneNumbers' } ], proxy:{ type:'ajax', url:'assoc/data/contacts.json', reader:{ type:'json', root:'data' } } }); 

model/PhoneNumber.js :

 Ext.define('Assoc.model.PhoneNumber', { extend:'Ext.data.Model', fields:[ 'number', 'contact_id' ], proxy:{ type:'ajax', url:'assoc/data/phone-numbers.json', reader:{ type:'json', root:'data' } } }); 

data / contacts.json:

 { "data":[ { "id":1, "name":"neil", "phoneNumbers":[ { "id":999, "contact_id":1, "number":"9005551234" } ] } ] } 

data / phone-numbers.json

 { "data":[ { "id":7, "contact_id":1, "number":"6045551212" }, { "id":88, "contact_id":1, "number":"8009996541" }, ] } 

app.js :

 Ext.Loader.setConfig({ enabled:true }); Ext.application({ requires:[ 'Assoc.model.Contact' ], name:'Assoc', appFolder:'Assoc', launch:function(){ /* load child models that are in the response (uses associationKey): */ Assoc.model.Contact.load(1, { success: function(record){ console.log(record.phoneNumbers()); } }); /* load child models at will (uses foreignKey). this overwrites child model that are in the first load response */ Assoc.model.Contact.load(1, { success: function(record){ record.phoneNumbers().load({ callback:function(){ console.log(arguments); } }); } }); } }); 

[1] The store will use its proxy model. If necessary, you can always override the store proxy. You cannot use Model.load () if the model does not have a proxy.

+11
source

Your guess is wrong. You expect the WebSite store to load, but that’s not how it works. What you can do is the following (this is untested, but I do this in all my projects):

In your client grid, add a listener for the itemclick event to call the following method (showWebSites). It will receive the selected client entry containing the selected instance of APP.model.Client. Then, given that each client has a set of WebSites, the method will load the APP.store.Websites repository, and the client’s websites will be displayed in your view.

 showWebSites: function (sender, selectedClient) { Ext.StoreManager.lookup('APP.store.Websites') .loadData(selectedClient.data.WebSites); } 

Like this. I hope you find this helpful.

0
source

Source: https://habr.com/ru/post/1414285/


All Articles