123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
Ext.define('Dbn.override.data.ProxyStore', {
override: 'Ext.data.ProxyStore',
onBatchComplete: function (batch) {
var me = this,
operations = batch.getOperations(),
operationsCount = operations.length, i, j, k;
for (i = 0; i < operationsCount; i++) {
var operation = operations[i];
if (operation.wasSuccessful()/* && operation.getRequest().getAction() === 'update'*/) {
var reader = operation.getProxy().getReader(),
entityType = reader.getModel(),
idProperty = entityType.idProperty,
schema = entityType.schema,
includes = schema.hasAssociations(entityType) && reader.getImplicitIncludes(),
fieldExtractorInfo = reader.getFieldExtractorInfo(entityType.fieldExtractors),
resultSetRecords = operation.getResultSet().getRecords(),
resultSetRecordsCount = resultSetRecords.length,
// Here we collect changes in records which are not processed by standard store logic.
// Standard logic processes records which were in the request only.
recordsToProcess = [],
recordsProcessedByOperation = operation.getRecords(),
recordsProcessedByOperationCount = recordsProcessedByOperation.length;
// Get records which were not in request and require custom processing.
for (j = 0; j < resultSetRecordsCount; j++) {
var processed = false;
for (k = 0; k < recordsProcessedByOperationCount; k++) {
if (recordsProcessedByOperation[k].getId() == resultSetRecords[j][idProperty]) {
processed = true;
break;
}
}
if (!processed)
recordsToProcess.push(resultSetRecords[j]);
}
var recordsToProcessCount = recordsToProcess.length,
existingRecordsToRefresh = [],
unprocessedNewRecords = [];
for (j = 0; j < recordsToProcessCount; j++) {
var recordData = recordsToProcess[j], record;
if (!recordData.isModel) {
var extractedRecordData = Ext.clone(recordData);
record = reader.extractRecord(extractedRecordData, {}, entityType, includes, fieldExtractorInfo);
record.raw = extractedRecordData;
}
else {
record = recordData;
recordData = record.raw;
}
var existingRecord = me.getById(record.getId());
// IMPORTANT! Record should have 'isDeleted' field to let logic know how to process it.
if (existingRecord) {
//region Process existing records.
if (record.get('isDeleted')) {
//region Process deletion.
me.suspendAutoSync();
existingRecord.drop(false);
me.removedNodes.splice(me.removedNodes.indexOf(existingRecord), 1);
me.resumeAutoSync();
//endregion
}
else {
//region Update fields of existing record with new data from server.
// recordData usage is potentially dangerous: it will break logic if properties of models are mapped to other server-side response fields.
for (var entityProp in recordData) {
if (!recordData.hasOwnProperty(entityProp)) continue;
existingRecord.data[entityProp] = recordData[entityProp];
}
for (var assocProp in record.associations) {
//noinspection JSUnresolvedFunction
if (!record.associations.hasOwnProperty(assocProp)) continue;
delete existingRecord[record.associations[assocProp].instanceName];
existingRecord[record.associations[assocProp].instanceName] = record[record.associations[assocProp].instanceName];
}
existingRecordsToRefresh.push(existingRecord);
//endregion
}
//endregion
}
else {
// Collect new unprocessed records.
if (!record.get('isDeleted'))
unprocessedNewRecords.push(record);
}
}
// Fire refresh to notify listeners about made changes.
me.fireEvent('refresh', me, existingRecordsToRefresh);
// Processing of new records can differ for different types of stores: Store, TreeStore and so on.
me.processNewRecordsFromSync(unprocessedNewRecords);
}
}
return me.callParent(arguments);
},
processNewRecordsFromSync: Ext.emptyFn,
/**
* @private
* Filter function for updated records.
*/
filterUpdated: function (item) {
// ADDED !item.dropped
// only want dirty records, not phantoms that are valid
return item.dirty === true && !item.dropped && item.phantom !== true && item.isValid();
}
});