/** * @author Don Griffin * * This class is a base for all id generators. It also provides lookup of id generators by * their id. * * Generally, id generators are used to generate a primary key for new model instances. There * are different approaches to solving this problem, so this mechanism has both simple use * cases and is open to custom implementations. A {@link Ext.data.Model} requests id generation * using the {@link Ext.data.Model#idgen} property. * * # Identity, Type and Shared IdGenerators * * It is often desirable to share IdGenerators to ensure uniqueness or common configuration. * This is done by giving IdGenerator instances an id property by which they can be looked * up using the {@link #get} method. To configure two {@link Ext.data.Model Model} classes * to share one {@link Ext.data.SequentialIdGenerator sequential} id generator, you simply * assign them the same id: * * Ext.define('MyApp.data.MyModelA', { * extend: 'Ext.data.Model', * idgen: { * type: 'sequential', * id: 'foo' * } * }); * * Ext.define('MyApp.data.MyModelB', { * extend: 'Ext.data.Model', * idgen: { * type: 'sequential', * id: 'foo' * } * }); * * To make this as simple as possible for generator types that are shared by many (or all) * Models, the IdGenerator types (such as 'sequential' or 'uuid') are also reserved as * generator id's. This is used by the {@link Ext.data.UuidGenerator} which has an id equal * to its type ('uuid'). In other words, the following Models share the same generator: * * Ext.define('MyApp.data.MyModelX', { * extend: 'Ext.data.Model', * idgen: 'uuid' * }); * * Ext.define('MyApp.data.MyModelY', { * extend: 'Ext.data.Model', * idgen: 'uuid' * }); * * This can be overridden (by specifying the id explicitly), but there is no particularly * good reason to do so for this generator type. * * # Creating Custom Generators * * An id generator should derive from this class and implement the {@link #generate} method. * The constructor will apply config properties on new instances, so a constructor is often * not necessary. * * To register an id generator type, a derived class should provide an `alias` like so: * * Ext.define('MyApp.data.CustomIdGenerator', { * extend: 'Ext.data.IdGenerator', * alias: 'idgen.custom', * * configProp: 42, // some config property w/default value * * generate: function () { * return ... // a new id * } * }); * * Using the custom id generator is then straightforward: * * Ext.define('MyApp.data.MyModel', { * extend: 'Ext.data.Model', * idgen: 'custom' * }); * // or... * * Ext.define('MyApp.data.MyModel', { * extend: 'Ext.data.Model', * idgen: { * type: 'custom', * configProp: value * } * }); * * It is not recommended to mix shared generators with generator configuration. This leads * to unpredictable results unless all configurations match (which is also redundant). In * such cases, a custom generator with a default id is the best approach. * * Ext.define('MyApp.data.CustomIdGenerator', { * extend: 'Ext.data.SequentialIdGenerator', * alias: 'idgen.custom', * * id: 'custom', // shared by default * * prefix: 'ID_', * seed: 1000 * }); * * Ext.define('MyApp.data.MyModelX', { * extend: 'Ext.data.Model', * idgen: 'custom' * }); * * Ext.define('MyApp.data.MyModelY', { * extend: 'Ext.data.Model', * idgen: 'custom' * }); * * // the above models share a generator that produces ID_1000, ID_1001, etc.. * */ Ext.define('Ext.data.IdGenerator', { /** * @property {Boolean} isGenerator * `true` in this class to identify an object as an instantiated IdGenerator, or subclass thereof. */ isGenerator: true, /** * Initializes a new instance. * @param {Object} config (optional) Configuration object to be applied to the new instance. */ constructor: function(config) { var me = this; Ext.apply(me, config); if (me.id) { Ext.data.IdGenerator.all[me.id] = me; } }, /** * @cfg {String} id * The id by which to register a new instance. This instance can be found using the * {@link Ext.data.IdGenerator#get} static method. */ getRecId: function (rec) { return rec.modelName + '-' + rec.internalId; }, /** * Generates and returns the next id. This method must be implemented by the derived * class. * * @return {String} The next id. * @method generate * @abstract */ statics: { /** * @property {Object} all * This object is keyed by id to lookup instances. * @private * @static */ all: {}, /** * Returns the IdGenerator given its config description. * @param {String/Object} config If this parameter is an IdGenerator instance, it is * simply returned. If this is a string, it is first used as an id for lookup and * then, if there is no match, as a type to create a new instance. This parameter * can also be a config object that contains a `type` property (among others) that * are used to create and configure the instance. * @static */ get: function (config) { var generator, id, type; if (typeof config == 'string') { id = type = config; config = null; } else if (config.isGenerator) { return config; } else { id = config.id || config.type; type = config.type; } generator = this.all[id]; if (!generator) { generator = Ext.create('idgen.' + type, config); } return generator; } } });