I am curious as to why the record contained in the result set of a Model.save()
response does not properly return updated associated data, despite the updated data being contained in the server response...
Example Model & Store Definition:
Ext.define("App.model.test.Parent",{
extend: 'Ext.data.Model',
requires: ['App.model.test.Child'],
fields: [
{name: 'id', type: 'int' },
{name: 'name', type: 'string'},
{name: 'kids', type: 'auto', defaultValue: []}
],
idProperty: 'id',
hasMany: [{
foreignKey: 'parent_id',
model: 'App.model.test.Child',
associationKey: 'kids',
name: 'getKids'
}],
proxy: {
type: 'ajax',
api : {
create: '/service/test/create/format/json',
read : '/service/test/read/format/json',
update : '/service/test/update/format/json'
},
reader: {
idProperty : 'id',
type : 'json',
root : 'data',
successProperty : 'success',
messageProperty : 'message'
},
writer: {
type : 'json',
writeAllFields : true
}
}
});
Ext.define("App.model.test.Child",{
extend: 'Ext.data.Model',
fields: [
{name: 'id', type: 'int' },
{name: 'name', type: 'string'},
{name: 'parent_id', type: 'int'}
]
});
Ext.define("App.store.test.Simpson",{
storeId: 'TheSimpsons',
extend: 'Ext.data.Store',
model : 'App.model.test.Parent',
autoLoad: true,
autoSync: false
});
The application server response to the proxy's READ
request with a single model, and its associated data. This is all working hunky dory!
Server Response to READ Request
{
"data":{
"id":1,
"name":"Homer Simpson",
"children":{
"1":{
"id":1,
"name":"Bart Simpson"
},
"2":{
"id":2,
"name":"Lisa Simpson"
},
"3":{
"id":3,
"name":"Maggie Simpson"
}
}
},
"success":true,
"message":null
}
Thus far, everything is working according to plan...
store = Ext.create("App.store.test.Simpson");
homer = store.getById(1);
kids = homer.getKids().getRange();
console.log("The Simpson Kids", kids); // [>constructor, >constructor, >constructor]
THE UNDESIRED BEHAVIOR BEGINS WITH SAVE AND UPDATE REQUESTS
Here is my test response for the UPDATE Request...
/** Server UPDATE Response */
{
"data":{
"id":1,
"name":"SAVED Homer Simpson",
"kids":[{
"id":1,
"name":"SAVED Bart Simpson",
"parent_id":1
},{
"id":2,
"name":"SAVED Lisa Simpson",
"parent_id":1
},{
"id":3,
"name":"SAVED Maggie Simpson",
"parent_id":1
}]
},
"success":true,
"message":null
}
/** Will call proxy UPDATE, response is above */
homer.save({
success: function(rec, op){
var savedRec = op.getRecords().pop(),
kidNames = '';
console.log(savedRec.get('name')); // SAVED Homer Simpson = CORRECT!
Ext.each(savedRec.getKids().getRange(), function(kid){
kidNames += kid.get('name') + ", ";
});
console.log(kids);
//Outputs: Bart Simpson, Lisa Simpson, Maggie Simpson = WRONG!!
}
})
I notice that if I inspect the record returned by the server, the generated Association Store (i.e., getKidsStore
) the contained records are the original records, i.e., they do not have "SAVED" in their name. The kids
property of the returned record, however, DOES indeed contain the correct data.
If I understand the issue correctly, it is that the Ext.data.reader.Reader
does not correctly update the associated store with the associated data contained in the .save()
response. If so, in my opinion, this is very unintuitive as I would expect the same behavior as the reader that handles the store.load()
request and populates the generated association stores to begin with.
Can anyone point me in the right direction in achieving the behavior I'm after?
Disclaimer: Same question was asked here: ExtJs 4 - Load nested data on record save but with no response. I feel my question to be a bit more thorough..
EDIT: I have posted this question over on the Sencha forums: http://www.sencha.com/forum/showthread.php?270336-Associated-Data-in-Model.save()-Response
EDIT (8/23/13): I re-wrote this post with a COMPLETE example, as well as additional findings...