Last active
August 29, 2015 14:01
-
-
Save yuristrelets/9b543be8cd8af27d0cd9 to your computer and use it in GitHub Desktop.
ExtJS advanced model that is able to update hasMany associations.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Improved {@link Ext.data.Model}. | |
* Can automatically update foreign keys and default filter value for hasMany associations. | |
*/ | |
Ext.define('App.model.AssocModel', { | |
extend: 'Ext.data.Model', | |
/** | |
* @private | |
* Copies data from the passed record into this record. If the passed record is undefined, does nothing. | |
* | |
* If this is a phantom record (represented only in the client, with no corresponding database entry), and | |
* the source record is not a phantom, then this record acquires the id of the source record. | |
* | |
* ADDED: If this is a phantom record and has hasMany associations, then foreign keys, filter value and `modelDefault` store property | |
* for this associations will be updated. | |
* | |
* @param {Ext.data.Model} sourceRecord The record to copy data from. | |
* @return {String[]} The names of the fields which changed value. | |
*/ | |
copyFrom: function(sourceRecord) { | |
var me = this, | |
fields = me.fields.items, | |
fieldCount = fields.length, | |
modifiedFieldNames = [], | |
field, i = 0, | |
myData, | |
sourceData, | |
idProperty = me.idProperty, | |
name, | |
value; | |
if(sourceRecord) { | |
myData = me[me.persistenceProperty]; | |
sourceData = sourceRecord[sourceRecord.persistenceProperty]; | |
for (; i < fieldCount; i++) { | |
field = fields[i]; | |
name = field.name; | |
// Do not use setters. | |
// Copy returned values in directly from the data object. | |
// Converters have already been called because new Records | |
// have been created to copy from. | |
// This is a direct record-to-record value copy operation. | |
// don't copy the id, we'll do it at the end | |
if (name != idProperty) { | |
value = sourceData[name]; | |
// If source property is specified, and value is different | |
// copy field value in and build updatedFields | |
if (value !== undefined && !me.isEqual(myData[name], value)) { | |
myData[name] = value; | |
modifiedFieldNames.push(name); | |
} | |
} | |
} | |
// If this is a phantom record being updated from a concrete record, copy the ID in. | |
if (me.phantom && !sourceRecord.phantom) { | |
// beginEdit to prevent events firing | |
// commit at the end to prevent dirty being set | |
me.beginEdit(); | |
me.setId(sourceRecord.getId()); | |
// update nasMany associations | |
me.updateHasManyAssociations(sourceRecord.getId()); | |
me.endEdit(true); | |
me.commit(true); | |
} | |
} | |
return modifiedFieldNames; | |
}, | |
/** | |
* @private | |
* Update foreign key value for hasMany associations. | |
* @param {int} newId | |
*/ | |
updateHasManyAssociations: function(newId) { | |
var me = this, | |
associations = me.associations.items, | |
associationCount = associations.length, | |
association, associatedStore, | |
type, name, foreignKey, filterProperty, | |
filters, filter; | |
for(var i = 0; i < associationCount; i++) { | |
association = associations[i]; | |
type = association.type; | |
name = association.name; | |
foreignKey = association.foreignKey; | |
filterProperty = association.filterProperty || foreignKey; | |
switch(type) { | |
case 'hasMany': | |
associatedStore = me[association.storeName]; | |
if(associatedStore) { | |
// update store associated foreign key fields | |
// for items are already added to store | |
// | |
if(associatedStore.getCount() > 0) { | |
associatedStore.each(function(item) { | |
item.set(foreignKey, newId); | |
}); | |
} | |
// update store `modelDefaults` foreign key property | |
// for future items | |
// | |
associatedStore.modelDefaults[filterProperty] = newId; | |
// update store filter value | |
// for saving/loading store operations | |
// | |
filters = associatedStore.filters; | |
filter = filters.getAt(filters.findIndex('property', filterProperty)); | |
if(filter) { | |
filter.setValue(newId); | |
} | |
} | |
break; | |
} | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment