-
28 Mar 2012 8:31 AM #1
getAssociatedData in Model return also the field tagged as non persistent
getAssociatedData in Model return also the field tagged as non persistent
Hi,
I'm using the getAssociatedData method in order to save my nested data.
In order to do so I've overwritten the getRecordData method of my Writer like this :
Everything works fine, except that the field defined as non persistent (persist:false) are also returned by the getAssociatedData method.Code:getRecordData: function(record) { record.set(record.getAssociatedData()); return Ext.data.writer.Json.prototype.getRecordData(record); }
I think this shouldn't be the case.
What do you think ?
Best regards
Daniel
-
28 Mar 2012 11:10 AM #2Sencha - Senior Forum Manager
- Join Date
- Mar 2007
- Location
- St. Louis, MO
- Posts
- 33,599
- Vote Rating
- 434
persist will only exclude that field from the modified fields so if you do getAssociatedData, there is nothing that will stop it from returning the field.
Mitchell Simoens @SenchaMitch
Sencha Inc, Senior Forum Manager
________________
http://www.JSONPLint.com - Source to lint your JSONP!
Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
https://github.com/mitchellsimoens
Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/
Need more help with your app? Hire Sencha Services services@sencha.com
Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is almost in print!
When posting code, please use BBCode's CODE tags.
-
4 May 2012 4:18 AM #3
This is an override wich implements the requested feature it surely can be done better, but this works, i've checked that :-D. Also this is for 4.1.
Hope it helps.
P.S.: Al code is standard extjs or copied from this forum, i've just added some little pieces here and there.
To use it you just need to declare the writer as a DeepJson:Code:Ext.define('Zll.data.model.GetDataPatch',{ override:'Ext.data.Model', getData: function(includeAssociated,excludeNotPersisted){ var me = this, fields = me.fields.items, fLen = fields.length, data = {}, name, f, persistent; persistent = (excludeNotPersisted == undefined)?false:excludeNotPersisted; for (f = 0; f < fLen; f++) { if (!persistent) { name = fields[f].name; data[name] = me.get(name); } else { if(fields[f].persist) { console.log('prova'); name = fields[f].name; data[name] = me.get(name); } } } if (includeAssociated === true) { Ext.apply(data, me.getAssociatedData()); } return data; }, getAssociatedData: function(persistedFields){ return this.prepareAssociatedData({}, 1,persistedFields); }, /** * @private * This complex-looking method takes a given Model instance and returns an object containing all data from * all of that Model's *loaded* associations. See {@link #getAssociatedData} * @param {Object} seenKeys A hash of all the associations we've already seen * @param {Number} depth The current depth * @return {Object} The nested data set for the Model's loaded associations */ prepareAssociatedData: function(seenKeys, depth,persistedFields) { /** * In this method we use a breadth first strategy instead of depth * first. The reason for doing so is that it prevents messy & difficult * issues when figuring out which associations we've already processed * & at what depths. */ var me = this, associations = me.associations.items, associationCount = associations.length, associationData = {}, // We keep 3 lists at the same index instead of using an array of objects. // The reasoning behind this is that this method gets called a lot // So we want to minimize the amount of objects we create for GC. toRead = [], toReadKey = [], toReadIndex = [], associatedStore, associatedRecords, associatedRecord, o, index, result, seenDepth, associationId, associatedRecordCount, association, i, j, type, name; for (i = 0; i < associationCount; i++) { association = associations[i]; associationId = association.associationId; seenDepth = seenKeys[associationId]; if (seenDepth && seenDepth !== depth) { continue; } seenKeys[associationId] = depth; type = association.type; name = association.name; if (type == 'hasMany') { //this is the hasMany store filled with the associated data associatedStore = me[association.storeName]; //we will use this to contain each associated record's data associationData[name] = []; //if it's loaded, put it into the association data if (associatedStore && associatedStore.getCount() > 0) { associatedRecords = associatedStore.data.items; associatedRecordCount = associatedRecords.length; //now we're finally iterating over the records in the association. Get // all the records so we can process them for (j = 0; j < associatedRecordCount; j++) { associatedRecord = associatedRecords[j]; associationData[name][j] = associatedRecord.getData(false,persistedFields); toRead.push(associatedRecord); toReadKey.push(name); toReadIndex.push(j); } } } else if (type == 'belongsTo' || type == 'hasOne') { associatedRecord = me[association.instanceName]; // If we have a record, put it onto our list if (associatedRecord !== undefined) { associationData[name] = associatedRecord.getData(false,persistedFields); toRead.push(associatedRecord); toReadKey.push(name); toReadIndex.push(-1); } } } for (i = 0, associatedRecordCount = toRead.length; i < associatedRecordCount; ++i) { associatedRecord = toRead[i]; o = associationData[toReadKey[i]]; index = toReadIndex[i]; result = associatedRecord.prepareAssociatedData(seenKeys, depth + 1); if (index === -1) { Ext.apply(o, result); } else { Ext.apply(o[index], result); } } return associationData; } }); Ext.define('Zll.data.writer.DeepJson', { extend : 'Ext.data.writer.Json', alternateClassName : 'Ext.data.DeepJsonWriter', alias : 'writer.deepjson', getRecordData : function(record) { var data = this.callParent(arguments); var associated = record.getAssociatedData(true); for (name in associated) { console.log(name); console.log(associated[name]); data[name] = associated[name]; } return data; } });
Code:.... writer: Ext.create('Zll.data.writer.DeepJson',{ allowSingle: false, writeAllFields: true }) ....Last edited by ZIOLele; 4 May 2012 at 4:20 AM. Reason: Added example of use
-
31 Jan 2013 2:38 AM #4
Nice fun-fact. This might not be a bug but rather a feature request.
I get it that you should be able to get all data but shouldn't you be able to get all data that needs to be persisted too? A field marked as persistent: false is expected not to be included.
I like ZIOLele 's override. Thank you very much!
Looks like we can't reproduce the issue or there's a problem in the test case provided.


Reply With Quote