PDA

View Full Version : HasOne association from nested json?



desp
31 Oct 2012, 3:31 AM
Hello,
there is possible to fetch whole associated from single json with hasMany association, but I can not achieve this with hasOne.

I need like this:


associations: [
{type: 'hasOne', model: 'myApp.model.Record', name: 'myRecord'}
]



from json:
{
"id": 1,
"name": "Some stuff",
"myRecord": {
...
}
.....
}

kevin.chen
1 Nov 2012, 6:30 PM
you can do it, you just don't know how to access it, if you give instanceName in your association, then you can access the nested data by parent.instanceName

desp
2 Nov 2012, 6:39 AM
There is no instanceName in http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.association.HasOne

kevin.chen
2 Nov 2012, 9:30 AM
well, you can try assocationKey since 'instanceName' is not documented.

for me, I have no problem to use instanceName

you can check out hasOne constructor, it is there.



constructor: function(config) {
this.callParent(arguments);


var me = this,
ownerProto = me.ownerModel.prototype,
associatedName = me.associatedName,
getterName = me.getterName || 'get' + associatedName,
setterName = me.setterName || 'set' + associatedName;


Ext.applyIf(me, {
name : associatedName,
foreignKey : associatedName.toLowerCase() + "_id",
instanceName: associatedName + 'HasOneInstance',
associationKey: associatedName.toLowerCase()
});


ownerProto[getterName] = me.createGetter();
ownerProto[setterName] = me.createSetter();
}

kevin.chen
2 Nov 2012, 9:33 AM
regarding associated model , I have one example I did for xml. you can take a look as reference



Ext.define('app.model.MyModel',{
extend: 'Ext.data.Model',
fields: [
{ name: 'myId', mapping: '@id', type: 'string'}
],
idProperty: 'myId',
associations: [
{
type: 'hasMany',
model: 'app.model.Person',
name: 'persons',
reader: {
type: 'xml',
root: 'persons',
record: '>person'
}
},
{
type: 'hasMany',
model: 'app.model.Product',
name: 'products',
reader: {
type: 'xml',
root: 'products',
record: '>product'
}
}


]


});




Ext.define('app.model.Person', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', mapping: '@id', type: 'string'},
{ name: 'name', mapping: '>name', type: 'string'},
{ name: 'gender', mapping: '>gender',type: 'string'}
],
associations: [{ type: 'hasOne',
model: 'app.model.Address',
associationKey: 'address',
instanceName: 'address1',
name: 'address',
reader: {
type: 'xml',
root: 'address',
record: 'address'
}
}]
});




Ext.define('app.model.Address', {
extend: 'Ext.data.Model',
fields: [
{ name: 'street', mapping: '>street', type: 'string'},
{ name: 'city', mapping: '>city', type: 'string'},
{ name: 'state', mapping: '>state', type: 'string'},
{ name: 'country', mapping: '>country', type: 'string'}
]
});






Ext.define('app.model.Product', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', mapping: '@id', type: 'string'},
{ name: 'name', mapping: '>name', type: 'string'}
],
associations: [
{
type: 'hasMany',
model: 'app.model.User',
name: 'users',
reader: {
type: 'xml',
root: 'users',
record: '>user'
}
}
]
});




Ext.define('app.model.User', {
extend: 'Ext.data.Model',
fields: [
{ name: 'id', mapping: '>id', type: 'string'},
{ name: 'name', mapping: '>name', type: 'string'}
]
});

kevin.chen
2 Nov 2012, 9:34 AM
here is the test data



<?xml version="1.0" encoding="utf-8"?>
<data>
<persons>
<person id="uid_01">
<name>Jhon</name>
<gender>Male</gender>
<address>
<street>Timberlake</street>
<city>Croydon</city>
<state>London</state>
<country>England</country>
</address>
</person>
<person id="uid_02">
<name>Leon</name>
<gender>Male</gender>
<address>
<street>306 Division Street</street>
<city>King City</city>
<state>California</state>
<country>United States</country>
</address>
</person>
</persons>
<products>
<product id="cos_timm001">
<name>Trimmer</name>
<users>
<user>
<id>uid_01</id>
<name>Jhon</name>
</user>
<user>
<id>uid_0901</id>
<name>Tom</name>
</user>
</users>
</product>
<product id="cos_cell001">
<name>IPhone5</name>
<users>
<user>
<id>uid_02</id>
<name>Leon</name>
</user>
</users>
</product>
</products>
</data>

kevin.chen
2 Nov 2012, 9:43 AM
you can access first person address by following (instanceName=address1)



Ext.getStore('MyStore').data.items[0].persons().data.items[0].address1


access second person's address by following(instancName=address1)



Ext.getStore('MyStore').data.items[0].persons().data.items[1].address1

adrianmirjan
29 Nov 2012, 6:35 AM
The above did not work for me in ExtJS 4.1.2

I think we should file a bug. HasOne association is not able to read nested data and always tries to request for the record from the server.

matej.kenda
15 Jan 2014, 3:09 AM
It seems that the same problem (hasOne wants to read from the server for nested resource) is present in ExtJS 4.2.2 as well.