/** * @class Ext.data.Session * @extend Ext.Base * @mixins Ext.mixin.Dirty * @mixins Ext.mixin.Observable * This class manages models and their associations. Instances of `Session` are typically * associated with some `Component` (perhaps the Viewport or a Window) and then used by * their `{@link Ext.app.ViewModel view models}` to enable data binding. * * The primary job of a Session is to manage a collection of records of many different * types and their associations. This often starts by loading records when requested (via * bind - see below) and culminates when it is time to save to the server. * * Because the Session tracks all records it loads, it ensures that for any given type of * model, only one record exists with a given `id`. This means that all edits of that * record are properly targeted at that one instance. * * Similarly, when associations are loaded, the `Ext.data.Store` created to hold the * associated records is tracked by the Session. So all requests for the "OrderItems" of * a particular Order id will result in the same Store. Adding and removing items from * that Order then is sure to remain consistent. * * # Data * * Since the Session is managing all this data, there are several methods it provides * to give convenient access to that data. The most important of these is `update` and * `getChanges`. * * The `update` and `getChanges` methods both operate on object that contains a summary * of records and associations and different CRUD operations. * * ## Saving * * There are two basic ways to save the contents of a Session: `getChanges` and * `getSaveBatch`. We've already seen `getChanges`. The data contained in the CRUD object * can be translated into whatever shape is needed by the server. * * To leverage the `{@link Ext.data.Model#proxy proxy}` facilities defined by each Model * class, there is the `getSaveBatch` method. That method returns an `Ext.data.Batch` * object populated with the necessary `create`, `update` and `destory` operations to * save all of the changes in the Session. * * ## Conflicts * * If data is loaded from the server (for example a store load) and there is an existing record, * the {@link Ext.data.Model#method-mergeData `mergeData`} method will be called to resolve the conflict. * * @since 5.0.0 */ /** * @cfg {String/Ext.data.schema.Schema} [schema='default'] * @accessor */ /** * @cfg {Ext.data.Session} [parent=null] * The parent session for this session. * @accessor */ /** * @cfg {Boolean} [autoDestroy=true] * `true` to automatically destroy this session when a component it is attached * to is destroyed. This should be set to false if the session is intended to be * used across multiple root level components. * * @accessor * @since 5.0.1 */ /** * @method adopt * Adds an existing record instance to the session. The record * may not belong to another session. The record cannot be a phantom record, instead * use {@link #createRecord}. * @param {Ext.data.Model} record The record to adopt. */ /** * @method commit * Marks the session as "clean" by calling {@link Ext.data.Model#commit} on each record * that is known to the session. * * - Phantom records will no longer be phantom. * - Modified records will no longer be dirty. * - Dropped records will be erased. * * @since 5.1.0 */ /** * @method createRecord * Creates a new record and tracks it in this session. * * @param {String/Ext.Class} type The `entityName` or the actual class of record to create. * @param {Object} [data] The data for the record. * @return {Ext.data.Model} The new record. */ /** * @method getChanges * Returns an object describing all of the modified fields, created or dropped records * and many-to-many association changes maintained by this session. * * @return {Object} An object in the CRUD format (see the intro docs). `null` if there are no changes. */ /** * @method getRecord * Get a cached record from the session. If the record does not exist, it will * be created. If the `autoLoad` parameter is not set to `false`, the record will * be loaded via the {@link Ext.data.Model#proxy proxy} of the Model. * * If this session is configured with a `{@link #parent}` session, a *copy* of any existing record * in the `parent` will be adopted into this session. If the `parent` does not contain the record, * the record will be created and *not* inserted into the parent. * * See also {@link #peekRecord}. * * @param {String/Ext.Class/Ext.data.Model} type The `entityName` or the actual class of record to create. * This may also be a record instance, where the type and id will be inferred from the record. If the record is * not attached to a session, it will be adopted. If it exists in a parent, an appropriate copy will be made as * described. * @param {Object} id The id of the record. * @param {Boolean/Object} [autoLoad=true] `false` to prevent the record from being loaded if * it does not exist. If this parameter is an object, it will be passed to the {@link Ext.data.Model#load} call. * @return {Ext.data.Model} The record. */ /** * @method getSaveBatch * Returns an `Ext.data.Batch` containing the `Ext.data.operation.Operation` instances * that are needed to save all of the changes in this session. This sorting is based * on operation type, associations and foreign keys. Generally speaking the operations * in the batch can be committed to a server sequentially and the server will never be * sent a request with an invalid (client-generated) id in a foreign key field. * * @param {Boolean} [sort=true] Pass `false` to disable the batch operation sort. * @return {Ext.data.Batch} */ /** * @method peekRecord * Gets an existing record from the session. The record will *not* be created if it does * not exist. * * See also: {@link #getRecord}. * * @param {String/Ext.Class} type The `entityName` or the actual class of record to create. * @param {Object} id The id of the record. * @param {Boolean} [deep=false] `true` to consult * @return {Ext.data.Model} The record, `null` if it does not exist. */ /** * @method save * Save any changes in this session to a {@link #parent} session. */ /** * @method spawn * Create a child session with this session as the {@link #parent}. * @return {Ext.data.Session} The copied session. */ /** * @method update * Complete a bulk update for this session. * @param {Object} data Data in the CRUD format (see the intro docs). */ /** * @method getEntityList * Transforms a list of ids into a list of records for a particular type. * @param {Ext.Class} entityType The entity type. * @param {Object[]} ids The ids to transform. * @return {Ext.data.Model[]} The models corresponding to the ids. */ /** * @method getModelIdentifier * Gets a user friendly identifier for a Model. * @param {Ext.Class} entityType The entity type. * @param {Object} id The id of the entity. * @return {String} The identifier. */ /** * @method visitData * Walks the internal data tracked by this session and calls methods on the provided * `visitor` object. The visitor can then accumulate whatever data it finds important. * The visitor object can provide a number of methods, but all are optional. * * This method does not enumerate associations since these can be traversed given the * records that are enumerated. For many-to-many associations, however, this method * does enumerate the changes because these changes are not "owned" by either side of * such associations. * * @param {Object} visitor * @param {Function} [visitor.onCleanRecord] This method is called to describe a record * that is known but unchanged. * @param {Ext.data.Model} visitor.onCleanRecord.record The unmodified record. * @param {Function} [visitor.onDirtyRecord] This method is called to describe a record * that has either been created, dropped or modified. * @param {Ext.data.Model} visitor.onDirtyRecord.record The modified record. * @param {Function} [visitor.onMatrixChange] This method is called to describe a * change in a many-to-many association (a "matrix"). * @param {Ext.data.schema.Association} visitor.onMatrixChange.association The object * describing the many-to-many ("matrix") association. * @param {Mixed} visitor.onMatrixChange.leftId The `idProperty` of the record on the * "left" of the association. * @param {Mixed} visitor.onMatrixChange.rightId The `idProperty` of the record on the * "right" of the association. * @param {Number} visitor.onMatrixChange.state A negative number if the two records * are being disassociated or a positive number if they are being associated. For * example, when adding User 10 to Group 20, this would be 1. When removing the User * this argument would be -1. * @return {Object} The visitor instance */