/** * Base class for data object. */Ext.define('Ext.exporter.data.Base', { requires: [ 'Ext.util.Collection' ], config: { /** * @cfg {String} idPrefix * * Prefix to use when generating the id. * * @private */ idPrefix: 'id', /** * @cfg {String} id * * Unique id for this object. Auto generated when missing. */ id: null, /** * @cfg {Boolean} autoGenerateId * * Set to `true` to auto generate an id if none is defined. */ autoGenerateId: true, /** * @cfg {String[]} autoGenerateKey * * Set an array of config names available on this class that will * be used to generate a key. This key is useful when instances * of this class are used in a {@link Ext.util.Collection}. * * The key is generated by combining the values of those configs. * If a config value is an instance of a class then it will look * for a getKey function on that class and use it. * * Set to false if you don't want to generate they key */ autoGenerateKey: { $value: false, merge: function(newValue, oldValue) { return newValue ? Ext.concat(newValue, oldValue || null) : false; } } }, // keep references to internal collections to easily destroy them internalCols: null, clearPropertiesOnDestroy: false, constructor: function(config) { var me = this; me.internalCols = []; me.initConfig(config); if (!me._id) { me.setId(null); } return me.callParent([config]); }, destroy: function() { this.destroyCollections(); this.callParent(); this.internalCols = null; }, destroyCollections: function() { var cols = this.internalCols, len = cols.length, i, j, length, col; for (i = 0; i < len; i++) { col = cols[i]; length = col.length; for (j = 0; j < length; j++) { col.items[j].destroy(); } col.destroy(); } cols.length = 0; }, clearCollections: function(cols) { var i, len, col; cols = cols ? Ext.Array.from(cols) : this.internalCols; len = cols.length; for (i = len - 1; i >= 0; i--) { col = cols[i]; if (col) { col.destroy(); } Ext.Array.remove(this.internalCols, col); } }, applyId: function(data) { var id; if (!data && this._autoGenerateId) { id = this._idPrefix + (++Ext.idSeed); } else { id = data; } return id; }, /** * This method could be used in config appliers that need to initialize a * Collection that has items of type className. * * @param data * @param dataCollection * @param className * @return {Ext.util.Collection} */ checkCollection: function(data, dataCollection, className) { var col; if (data) { col = this.constructCollection(className); col.add(data); } if (dataCollection) { Ext.Array.remove(this.internalCols, dataCollection); Ext.destroy(dataCollection.items, dataCollection); } return col; }, /** * Create a new Collection with a decoder for the specified className. * * @param className * @returns {Ext.util.Collection} * * @private */ constructCollection: function(className) { var cls = Ext.ClassManager.get(className), cfg = { decoder: this.getCollectionDecoder(cls) }, col; if (typeof cls.prototype.getKey === 'function') { cfg.keyFn = this.getCollectionItemKey; } col = new Ext.util.Collection(cfg); this.internalCols.push(col); return col; }, /** * Builds a Collection decoder for the specified className. * * @param klass * @returns {Function} * * @private */ getCollectionDecoder: function(klass) { return function(config) { return (config && config.isInstance) ? config : new klass(config || {}); }; }, /** * Returns a collection item key * * @param item * @return {String} * * @private */ getCollectionItemKey: function(item) { return item.getKey ? item.getKey() : (item._id || item.getId()); }, getKey: function() { var generate = this.getAutoGenerateKey(), key = '', config = this.getConfig(), len, i; if (!Ext.isArray(generate) || !generate.length) { return this.getId(); } len = generate.length; for (i = 0; i < len; i++) { key += this.serializeKeyValue(config[generate[i]]); } return key; }, serializeKeyValue: function(value) { var key = '', keys, len, i; if (value === null) { key = '_'; } else if (Ext.isDate(value)) { key = value.getTime(); } else if (Ext.isArray(value)) { len = value.length; for (i = 0; i < len; i++) { key += this.serializeKeyValue(value[i]); } } else if (typeof value === 'object') { if (value.isInstance) { key = value.getKey ? value.getKey() : '_'; } else { keys = Ext.Object.getAllKeys(value); keys = Ext.Array.sort(keys); len = keys.length; for (i = 0; i < len; i++) { key += this.serializeKeyValue(value[keys[i]]); } } } else { key = value; } return key; }});