/** * This class is used internally by `{@link Ext.data.Session#getChanges}` to build * up an object describing changes in the session. It is not intended for public use but * can be used as an example of the visitor `{@link Ext.data.Session#visitData}` * requires. * @protected * @since 5.0.0 */Ext.define('Ext.data.session.ChangesVisitor', { constructor: function (session) { var me = this, crud; me.session = session; crud = session.getCrudProperties(); me.result = null; me.writerOptions = { /* * Keyed by the $className of a Model, e.g. "Foo", and to cache data from * Foo.getProxy().getWriter (called "writer" in the pseudo code below): * * Foo: { * drop: { * all: writer.getWriteAllFields(), * }, * allDataOptions: Ext.apply(Ext.Object.chain(writer.getAllDataOptions()), { * serialize: true * }), * partialDataOptions: Ext.apply(Ext.Object.chain(writer.getPartialDataOptions()), { * serialize: true * }) * } */ }; me.createKey = crud.create; me.readKey = crud.read; me.updateKey = crud.update; me.dropKey = crud.drop; }, onDirtyRecord: function (record) { var me = this, crud = me.crud, created = record.phantom, dropped = record.dropped, updated = !created && !dropped, type = record.$className, prop = (created || dropped) ? 'allDataOptions' : 'partialDataOptions', writerOptions = me.writerOptions, name = record.entityName, options, bucket, entry, result; if (created && dropped) { return false; } crud = created ? me.createKey : (dropped ? me.dropKey : me.updateKey); writerOptions = writerOptions[type] || (writerOptions[type] = {}); if (dropped) { // If the Writer says "writeAllFields" then we want to use allDataOptions // for the prop (set already). Otherwise we just want to encode the id. if (!(options = writerOptions.drop)) { writerOptions.drop = options = { all: record.getProxy().getWriter().getWriteAllFields() }; } if (!options.all) { entry = record.id; } // else entry is unset so we'll ask for the prop and call record.getData } if (!entry) { // Consult the Writer for the entity to determine its preferences for writing // complete or partial data. We rely on the serialization of the record's // getData method whereas the Writer has its own ideas on the matter. if (!(options = writerOptions[prop])) { options = record.getProxy().getWriter().getConfig(prop); writerOptions[prop] = options = Ext.Object.chain(options); me.setupOptions(options); } entry = record.getData(options); } // User: { // C: [ // { id: 20, name: 'Don' } // ], // U: [ // { id: 30, name: 'Don' } // ], // D: [ 40, 50 ] // } result = me.result || (me.result = {}); bucket = result[name] || (result[name] = {}); bucket = bucket[crud] || (bucket[crud] = []); bucket.push(entry); }, setupOptions: function(options) { options.serialize = true; }, onMatrixChange: function (association, id1, id2, state) { var me = this, name = association.left.type, // e.g., "User" assocName = association.right.role, // e.g., "groups" operation = state < 0 ? me.dropKey : me.createKey, bucket, result; // User: { // groups: { // C: { // 20: [ 30, 40 ] // associate User 20 w/Groups 30 & 40 // }, // D: { // 10: [ 50 ] // disassociate User 10 w/Group 50 // } // } // } result = me.result || (me.result = {}); bucket = result[name] || (result[name] = {}); // User bucket = bucket[assocName] || (bucket[assocName] = {}); // groups bucket = bucket[operation] || (bucket[operation] = {}); // C or D bucket = bucket[id1] || (bucket[id1] = []); bucket.push(id2); }});