partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

Ext.data.Model-EXTJS-15037.js (7279B)


      1 /**
      2  * This is a bugfix when a save operation on a model does not update associations returned by the server.
      3  *
      4  * The forum thread can be found at https://www.sencha.com/forum/showthread.php?302635-Ext.data.operation.Operation.doProcess-doesn-t-update-associations&p=1106828
      5  */
      6 Ext.define("PartKeepr.data.Model", {
      7     override: 'Ext.data.Model',
      8 
      9     hasField: function (fieldName) {
     10         var fields = this.getFields();
     11 
     12 
     13         for (var i in fields) {
     14             if (fields[i].name == fieldName && fields[i].reference === null) {
     15                 return true;
     16             }
     17         }
     18 
     19         return false;
     20     },
     21     /**
     22      * Saves the model instance using the configured proxy.
     23      * @param {Object} [options] Options to pass to the proxy. Config object for {@link Ext.data.operation.Operation}.
     24      * @return {Ext.data.operation.Operation} The operation
     25      */
     26     save: function (options) {
     27         options = Ext.apply({}, options);
     28 
     29         var me = this,
     30             phantom = me.phantom,
     31             dropped = me.dropped,
     32             action = dropped ? 'destroy' : (phantom ? 'create' : 'update'),
     33             scope = options.scope || me,
     34             callback = options.callback,
     35             proxy = me.getProxy(),
     36             operation;
     37 
     38         options.records = [me];
     39 
     40         options.recordCreator = function (data, type, readOptions) {
     41             // Important to change this here, because we might be loading associations,
     42             // so we do not want this to propagate down. If we have a session, use that
     43             // so that we end up getting the same record. Otherwise, just remove it.
     44             var session = me.session;
     45             if (readOptions) {
     46                 readOptions.recordCreator = session ? session.recordCreator : null;
     47             }
     48             me.set(data, me._commitOptions);
     49             //<debug>
     50             // Do the id check after set since converters may have run
     51             /*if (doIdCheck && me.getId() !== id) {
     52              Ext.Error.raise('Invalid record id returned for ' + id + '@' + me.entityName);
     53              }*/
     54             //</debug>
     55             return me;
     56         };
     57 
     58         options.internalCallback = function (operation) {
     59             var args = [me, operation],
     60                 success = operation.wasSuccessful();
     61             if (success) {
     62                 Ext.callback(options.success, scope, args);
     63             } else {
     64                 Ext.callback(options.failure, scope, args);
     65             }
     66             args.push(success);
     67             Ext.callback(callback, scope, args);
     68         };
     69         delete options.callback;
     70 
     71         operation = proxy.createOperation(action, options);
     72 
     73         // Not a phantom, then we must perform this operation on the remote datasource.
     74         // Record will be removed from the store in the callback upon a success response
     75         if (dropped && phantom) {
     76             // If it's a phantom, then call the callback directly with a dummy successful ResultSet
     77             operation.setResultSet(Ext.data.reader.Reader.prototype.nullResultSet);
     78             me.setErased();
     79             operation.setSuccessful(true);
     80         } else {
     81             operation.execute();
     82         }
     83         return operation;
     84     }
     85 });
     86 
     87 Ext.define('PartKeepr.data.operation.Update', {
     88     override: 'Ext.data.operation.Update',
     89 
     90     action: 'update',
     91 
     92     isUpdateOperation: true,
     93 
     94     order: 20,
     95     doProcess: Ext.emptyFn,
     96     doExecute: function () {
     97         return this.getProxy().update(this);
     98     }
     99 });
    100 
    101 Ext.define('PartKeepr.data.operation.Create', {
    102     override: 'Ext.data.operation.Create',
    103 
    104     action: 'create',
    105 
    106     isCreateOperation: true,
    107 
    108     order: 10,
    109     doProcess: Ext.emptyFn,
    110     doExecute: function() {
    111         return this.getProxy().create(this);
    112     }
    113 });
    114 
    115 Ext.define("PartKeepr.data.schema.Role", {
    116     override: "Ext.data.schema.Role",
    117 
    118     getAssociatedStore: function (inverseRecord, options, scope, records, isComplete) {
    119         // Consider the Comment entity with a ticketId to a Ticket entity. The Comment
    120         // is on the left (the FK holder's side) so we are implementing the guts of
    121         // the comments() method to load the Store of Comment entities. This trek
    122         // begins from a Ticket (inverseRecord).
    123 
    124         var me = this,
    125             storeName = me.getStoreName(),
    126             store = inverseRecord[storeName],
    127             load = options && options.reload,
    128             source = inverseRecord.$source,
    129             session = inverseRecord.session,
    130             args, i, len, raw, rec, sourceStore;
    131 
    132         if (!store) {
    133             // We want to check whether we can automatically get the store contents from the parent session.
    134             // For this to occur, we need to have a parent in the session, and the store needs to be created
    135             // and loaded with the initial dataset.
    136             if (!records && source) {
    137                 source = source[storeName];
    138                 if (source && !source.isLoading()) {
    139                     sourceStore = source;
    140                     records = [];
    141                     raw = source.getData().items;
    142 
    143                     for (i = 0, len = raw.length; i < len; ++i) {
    144                         rec = raw[i];
    145                         records.push(session.getRecord(rec.self, rec.id));
    146                     }
    147                     isComplete = true;
    148                 }
    149             }
    150             store = me.createAssociationStore(session, inverseRecord, records, isComplete);
    151             store.$source = sourceStore;
    152 
    153             if (!records && (me.autoLoad || options)) {
    154                 load = true;
    155             }
    156 
    157             inverseRecord[storeName] = store;
    158         } else {
    159             if (records) {
    160                 store.loadData(records);
    161             }
    162         }
    163 
    164         if (options) {
    165             // We need to trigger a load or the store is already loading. Defer
    166             // callbacks until that happens
    167             if (load || store.isLoading()) {
    168                 store.on('load', function (store, records, success, operation) {
    169                     args = [store, operation];
    170                     scope = scope || options.scope || inverseRecord;
    171 
    172                     if (success) {
    173                         Ext.callback(options.success, scope, args);
    174                     } else {
    175                         Ext.callback(options.failure, scope, args);
    176                     }
    177                     args.push(success);
    178                     Ext.callback(options, scope, args);
    179                     Ext.callback(options.callback, scope, args);
    180                 }, null, {single: true});
    181             } else {
    182                 // Trigger straight away
    183                 args = [store, null];
    184                 scope = scope || options.scope || inverseRecord;
    185 
    186                 Ext.callback(options.success, scope, args);
    187                 args.push(true);
    188                 Ext.callback(options, scope, args);
    189                 Ext.callback(options.callback, scope, args);
    190             }
    191         }
    192 
    193         if (load && !store.isLoading()) {
    194             store.load();
    195         }
    196 
    197         return store;
    198     },
    199 });
    200 
    201 Ext.define("PartKeepr.data.proxy.Proxy", {
    202     override: "Ext.data.proxy.Proxy",
    203 
    204     batch: function (options, /* deprecated */listeners) {
    205         return this.callParent(arguments);
    206     }
    207 });