/ext-4.1.0_b3/src/data/Model.js
JavaScript | 1519 lines | 701 code | 162 blank | 656 comment | 149 complexity | 48e53a990f903d50d13e37ab49add77f MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /**
- * @author Ed Spencer
- *
- * A Model represents some object that your application manages. For example, one might define a Model for Users,
- * Products, Cars, or any other real-world object that we want to model in the system. Models are registered via the
- * {@link Ext.ModelManager model manager}, and are used by {@link Ext.data.Store stores}, which are in turn used by many
- * of the data-bound components in Ext.
- *
- * Models are defined as a set of fields and any arbitrary methods and properties relevant to the model. For example:
- *
- * Ext.define('User', {
- * extend: 'Ext.data.Model',
- * fields: [
- * {name: 'name', type: 'string'},
- * {name: 'age', type: 'int'},
- * {name: 'phone', type: 'string'},
- * {name: 'alive', type: 'boolean', defaultValue: true}
- * ],
- *
- * changeName: function() {
- * var oldName = this.get('name'),
- * newName = oldName + " The Barbarian";
- *
- * this.set('name', newName);
- * }
- * });
- *
- * The fields array is turned into a {@link Ext.util.MixedCollection MixedCollection} automatically by the {@link
- * Ext.ModelManager ModelManager}, and all other functions and properties are copied to the new Model's prototype.
- *
- * Now we can create instances of our User model and call any model logic we defined:
- *
- * var user = Ext.create('User', {
- * name : 'Conan',
- * age : 24,
- * phone: '555-555-5555'
- * });
- *
- * user.changeName();
- * user.get('name'); //returns "Conan The Barbarian"
- *
- * # Validations
- *
- * Models have built-in support for validations, which are executed against the validator functions in {@link
- * Ext.data.validations} ({@link Ext.data.validations see all validation functions}). Validations are easy to add to
- * models:
- *
- * Ext.define('User', {
- * extend: 'Ext.data.Model',
- * fields: [
- * {name: 'name', type: 'string'},
- * {name: 'age', type: 'int'},
- * {name: 'phone', type: 'string'},
- * {name: 'gender', type: 'string'},
- * {name: 'username', type: 'string'},
- * {name: 'alive', type: 'boolean', defaultValue: true}
- * ],
- *
- * validations: [
- * {type: 'presence', field: 'age'},
- * {type: 'length', field: 'name', min: 2},
- * {type: 'inclusion', field: 'gender', list: ['Male', 'Female']},
- * {type: 'exclusion', field: 'username', list: ['Admin', 'Operator']},
- * {type: 'format', field: 'username', matcher: /([a-z]+)[0-9]{2,3}/}
- * ]
- * });
- *
- * The validations can be run by simply calling the {@link #validate} function, which returns a {@link Ext.data.Errors}
- * object:
- *
- * var instance = Ext.create('User', {
- * name: 'Ed',
- * gender: 'Male',
- * username: 'edspencer'
- * });
- *
- * var errors = instance.validate();
- *
- * # Associations
- *
- * Models can have associations with other Models via {@link Ext.data.association.HasOne},
- * {@link Ext.data.association.BelongsTo belongsTo} and {@link Ext.data.association.HasMany hasMany} associations.
- * For example, let's say we're writing a blog administration application which deals with Users, Posts and Comments.
- * We can express the relationships between these models like this:
- *
- * Ext.define('Post', {
- * extend: 'Ext.data.Model',
- * fields: ['id', 'user_id'],
- *
- * belongsTo: 'User',
- * hasMany : {model: 'Comment', name: 'comments'}
- * });
- *
- * Ext.define('Comment', {
- * extend: 'Ext.data.Model',
- * fields: ['id', 'user_id', 'post_id'],
- *
- * belongsTo: 'Post'
- * });
- *
- * Ext.define('User', {
- * extend: 'Ext.data.Model',
- * fields: ['id'],
- *
- * hasMany: [
- * 'Post',
- * {model: 'Comment', name: 'comments'}
- * ]
- * });
- *
- * See the docs for {@link Ext.data.association.HasOne}, {@link Ext.data.association.BelongsTo} and
- * {@link Ext.data.association.HasMany} for details on the usage and configuration of associations.
- * Note that associations can also be specified like this:
- *
- * Ext.define('User', {
- * extend: 'Ext.data.Model',
- * fields: ['id'],
- *
- * associations: [
- * {type: 'hasMany', model: 'Post', name: 'posts'},
- * {type: 'hasMany', model: 'Comment', name: 'comments'}
- * ]
- * });
- *
- * # Using a Proxy
- *
- * Models are great for representing types of data and relationships, but sooner or later we're going to want to load or
- * save that data somewhere. All loading and saving of data is handled via a {@link Ext.data.proxy.Proxy Proxy}, which
- * can be set directly on the Model:
- *
- * Ext.define('User', {
- * extend: 'Ext.data.Model',
- * fields: ['id', 'name', 'email'],
- *
- * proxy: {
- * type: 'rest',
- * url : '/users'
- * }
- * });
- *
- * Here we've set up a {@link Ext.data.proxy.Rest Rest Proxy}, which knows how to load and save data to and from a
- * RESTful backend. Let's see how this works:
- *
- * var user = Ext.create('User', {name: 'Ed Spencer', email: 'ed@sencha.com'});
- *
- * user.save(); //POST /users
- *
- * Calling {@link #save} on the new Model instance tells the configured RestProxy that we wish to persist this Model's
- * data onto our server. RestProxy figures out that this Model hasn't been saved before because it doesn't have an id,
- * and performs the appropriate action - in this case issuing a POST request to the url we configured (/users). We
- * configure any Proxy on any Model and always follow this API - see {@link Ext.data.proxy.Proxy} for a full list.
- *
- * Loading data via the Proxy is equally easy:
- *
- * //get a reference to the User model class
- * var User = Ext.ModelManager.getModel('User');
- *
- * //Uses the configured RestProxy to make a GET request to /users/123
- * User.load(123, {
- * success: function(user) {
- * console.log(user.getId()); //logs 123
- * }
- * });
- *
- * Models can also be updated and destroyed easily:
- *
- * //the user Model we loaded in the last snippet:
- * user.set('name', 'Edward Spencer');
- *
- * //tells the Proxy to save the Model. In this case it will perform a PUT request to /users/123 as this Model already has an id
- * user.save({
- * success: function() {
- * console.log('The User was updated');
- * }
- * });
- *
- * //tells the Proxy to destroy the Model. Performs a DELETE request to /users/123
- * user.destroy({
- * success: function() {
- * console.log('The User was destroyed!');
- * }
- * });
- *
- * # Usage in Stores
- *
- * It is very common to want to load a set of Model instances to be displayed and manipulated in the UI. We do this by
- * creating a {@link Ext.data.Store Store}:
- *
- * var store = Ext.create('Ext.data.Store', {
- * model: 'User'
- * });
- *
- * //uses the Proxy we set up on Model to load the Store data
- * store.load();
- *
- * A Store is just a collection of Model instances - usually loaded from a server somewhere. Store can also maintain a
- * set of added, updated and removed Model instances to be synchronized with the server via the Proxy. See the {@link
- * Ext.data.Store Store docs} for more information on Stores.
- *
- * @constructor
- * Creates new Model instance.
- * @param {Object} data An object containing keys corresponding to this model's fields, and their associated values
- */
- Ext.define('Ext.data.Model', {
- alternateClassName: 'Ext.data.Record',
- mixins: {
- observable: 'Ext.util.Observable'
- },
- requires: [
- 'Ext.ModelManager',
- 'Ext.data.IdGenerator',
- 'Ext.data.Field',
- 'Ext.data.Errors',
- 'Ext.data.Operation',
- 'Ext.data.validations',
- 'Ext.data.proxy.Ajax',
- 'Ext.util.MixedCollection'
- ],
- sortConvertFields: function(f1, f2) {
- var f1SpecialConvert = f1.type && f1.convert !== f1.type.convert,
- f2SpecialConvert = f2.type && f2.convert !== f2.type.convert;
- if (f1SpecialConvert && !f2SpecialConvert) {
- return 1;
- }
- if (!f1SpecialConvert && f2SpecialConvert) {
- return -1;
- }
- return 0;
- },
- itemNameFn: function(item) {
- return item.name;
- },
- onClassExtended: function(cls, data, hooks) {
- var onBeforeClassCreated = hooks.onBeforeCreated;
- hooks.onBeforeCreated = function(cls, data) {
- var me = this,
- name = Ext.getClassName(cls),
- prototype = cls.prototype,
-