Clear Up
SharpKit Reference

Model Class

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 model manager, and are used by 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', convert: null},
            {name: 'phone', type: 'string'},
            {name: 'alive', type: 'boolean', defaultValue: true, convert: null}
            ],
            changeName: function() {
            var oldName = this.get('name'),
            newName = oldName + " The Barbarian";
            this.set('name', newName);
            }
            });
            

The fields array is turned into a MixedCollection automatically by the ModelManager, and all other functions and properties are copied to the new Model's prototype.

By default, the built in numeric and boolean field types have a (@link Ext.data.Field.convert} function which coerces string values in raw data into the field's type. For better performance with Json or Array readers if you are in control of the data fed into this Model, you can null out the default convert function which will cause the raw property to be copied directly into the Field's value.

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 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 validate function, which returns a 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 Ext.data.association.HasOne, belongsTo and 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 Ext.data.association.HasOne, Ext.data.association.BelongsTo and 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 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 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 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 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 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 Store docs for more information on Stores.

Namespace: Ext.data

Base Types

Base Interfaces

Constructors

Name Description
Model(object) Creates new Model instance.
Model(ModelConfig)
Model()
Model(Object[])

Methods

Name Description
addEvents(object) Adds the specified events to the list of events which this Observable may fire.
addListener(object, Delegate, object, object) Appends an event handler to this object. For example:
myGridPanel.on("mouseover", this.onMouseOver, this);
            
The method also allows for a single argument to be passed which is a config object containing properties which specify multiple events. For example:
myGridPanel.on({
            cellClick: this.onCellClick,
            mouseover: this.onMouseOver,
            mouseout: this.onMouseOut,
            scope: this // Important. Ensure "this" is correct during handler execution
            });
            
One can also specify options for each event handler separately:
myGridPanel.on({
            cellClick: {fn: this.onCellClick, scope: this, single: true},
            mouseover: {fn: panel.onMouseOver, scope: panel}
            });
            
Names of methods in a specified scope may also be used. Note that scope MUST be specified to use this option:
myGridPanel.on({
            cellClick: {fn: 'onCellClick', scope: this, single: true},
            mouseover: {fn: 'onMouseOver', scope: panel}
            });
            
addManagedListener(object, object, Delegate, object, object) Adds listeners to any Observable object (or Ext.Element) which are automatically removed when this Component is destroyed.
beginEdit() Begins an edit. While in edit mode, no events (e.g.. the update event) are relayed to the containing store. When an edit has begun, it must be followed by either endEdit or cancelEdit.
cancelEdit() Cancels all changes made in the current edit operation.
clearListeners() Removes all listeners for this object including the managed listeners
clearManagedListeners() Removes all managed listeners for this object.
commit(object) Usually called by the Ext.data.Store which owns the model instance. Commits all changes made to the instance since either creation or the last commit operation. Developers should subscribe to the Ext.data.Store.update event to have their code notified of commit operations.
continueFireEvent(JsString, object, object) Continue to fire event.
copy(object) Creates a copy (clone) of this Model instance.
createRelayer(object, object) Creates an event handling function which refires the event from this object as the passed event name.
destroy(object) Destroys the model using the configured proxy.
enableBubble(object) Enables events fired by this Observable to bubble up an owner hierarchy by calling this.getBubbleTarget() if present. There is no implementation in the Observable base class. This is commonly used by Ext.Components to bubble events to owner Containers. See Ext.Component.getBubbleTarget. The default implementation in Ext.Component returns the Component's immediate owner. But if a known target is required, this can be overridden to access the required target more quickly. Example:
  Ext.override(Ext.form.field.Base, {
            //  Add functionality to Field's initComponent to enable the change event to bubble
            initComponent : Ext.Function.createSequence(Ext.form.field.Base.prototype.initComponent, function() {
            this.enableBubble('change');
            }),
            //  We know that we want Field's events to bubble directly to the FormPanel.
            getBubbleTarget : function() {
            if (!this.formPanel) {
            this.formPanel = this.findParentByType('form');
            }
            return this.formPanel;
            }
            });
            var myForm = new Ext.formPanel({
            title: 'User Details',
            items: [{
            ...
            }],
            listeners: {
            change: function() {
            // Title goes red if form has been modified.
            myForm.header.setStyle('color', 'red');
            }
            }
            });
            
endEdit(bool, object) Ends an edit. If any data was modified, the containing store is notified (ie, the store's update event will fire).
fireEvent(JsString, Object[]) Fires the specified event with the passed parameters (minus the event name, plus the options object passed to addListener). An event may be set to bubble up an Observable parent hierarchy (See Ext.Component.getBubbleTarget) by calling enableBubble.
get(JsString) Returns the value of the given field
getAssociatedData() Gets all of the data from this Models loaded associations. It does this recursively - for example if we have a User which hasMany Orders, and each Order hasMany OrderItems, it will return an object like this:
{
            orders: [
            {
            id: 123,
            status: 'shipped',
            orderItems: [
            ...
            ]
            }
            ]
            }
            
getBubbleParent() Gets the bubbling parent for an Observable
getChanges() Gets a hash of only the fields that have been modified since this Model was created or commited.
getData(bool) Gets all values for each field in this model and returns an object containing the current data.
getFields() Returns an Array of Field definitions which define this Model's structure Fields are sorted upon Model class definition. Fields with custom convert functions are moved to after fields with no convert functions. This is so that convert functions which rely on existing field values will be able to read those field values.
getId() Returns the unique ID allocated to this model instance as defined by idProperty.
getProxy() Returns the configured Proxy for this Model.
hasListener(JsString) Checks to see if this object has any listeners for a specified event, or whether the event bubbles. The answer indicates whether the event needs firing or not.
id(Model) Generates a sequential id. This method is typically called when a record is created and no id has been specified. The id will automatically be assigned to the record. The returned id takes the form: {PREFIX}-{AUTO_ID}.
  • PREFIX : String - Ext.data.Model.PREFIX (defaults to 'ext-record')
  • AUTO_ID : String - Ext.data.Model.AUTO_ID (defaults to 1 initially)
  • isModified(JsString) Returns true if the passed field name has been modified since the load or last commit.
    isValid() Checks if the model is valid. See validate.
    join(Store) Tells this model instance that it has been added to a store.
    load(object, object) Asynchronously loads a model instance by id. Sample usage:
      Ext.define('MyApp.User', {
                extend: 'Ext.data.Model',
                fields: [
                {name: 'id', type: 'int'},
                {name: 'name', type: 'string'}
                ]
                });
                MyApp.User.load(10, {
                scope: this,
                failure: function(record, operation) {
                //do something if the load failed
                },
                success: function(record, operation) {
                //do something if the load succeeded
                },
                callback: function(record, operation) {
                //do something whether the load succeeded or failed
                }
                });
                
    mon(object, object, Delegate, object, object) Shorthand for addManagedListener. Adds listeners to any Observable object (or Ext.Element) which are automatically removed when this Component is destroyed.
    mun(object, object, Delegate, object) Shorthand for removeManagedListener. Removes listeners that were added by the mon method.
    on(object, Delegate, object, object) Shorthand for addListener. Appends an event handler to this object. For example:
    myGridPanel.on("mouseover", this.onMouseOver, this);
                
    The method also allows for a single argument to be passed which is a config object containing properties which specify multiple events. For example:
    myGridPanel.on({
                cellClick: this.onCellClick,
                mouseover: this.onMouseOver,
                mouseout: this.onMouseOut,
                scope: this // Important. Ensure "this" is correct during handler execution
                });
                
    One can also specify options for each event handler separately:
    myGridPanel.on({
                cellClick: {fn: this.onCellClick, scope: this, single: true},
                mouseover: {fn: panel.onMouseOver, scope: panel}
                });
                
    Names of methods in a specified scope may also be used. Note that scope MUST be specified to use this option:
    myGridPanel.on({
                cellClick: {fn: 'onCellClick', scope: this, single: true},
                mouseover: {fn: 'onMouseOver', scope: panel}
                });
                
    prepareClass(Delegate) Prepares a given class for observable instances. This method is called when a class derives from this class or uses this class as a mixin.
    reject(object) Usually called by the Ext.data.Store to which this model instance has been joined. Rejects all changes made to the model instance since either creation, or the last commit operation. Modified fields are reverted to their original values. Developers should subscribe to the Ext.data.Store.update event to have their code notified of reject operations.
    relayEvents(object, JsArray<T>, object) Relays selected events from the specified Observable as if the events were fired by this. For example if you are extending Grid, you might decide to forward some events from store. So you can do this inside your initComponent:
    this.relayEvents(this.getStore(), ['load']);
                
    The grid instance will then have an observable 'load' event which will be passed the parameters of the store's load event and any function fired with the grid's load event would have access to the grid using the this keyword.
    removeListener(JsString, Delegate, object) Removes an event handler.
    removeManagedListener(object, object, Delegate, object) Removes listeners that were added by the mon method.
    removeManagedListenerItem(bool, object) Remove a single managed listener item
    resumeEvents() Resumes firing events (see suspendEvents). If events were suspended using the queueSuspended parameter, then all events fired during event suspension will be sent to any listeners now.
    save(object) Saves the model instance using the configured proxy.
    set(object, object) Sets the given field to the given value, marks the instance as dirty
    setDirty() Marks this Record as dirty. This method is used interally when adding phantom records to a writer enabled store. Marking a record dirty causes the phantom to be returned by Ext.data.Store.getUpdatedRecords where it will have a create action composed for it during model save operations.
    setFields(object, object, object) Apply a new set of field and/or property definitions to the existing model. This will replace any existing fields, including fields inherited from superclasses. Mainly for reconfiguring the model based on changes in meta data (called from Reader's onMetaChange method).
    setId(object) Sets the model instance's id field to the given id.
    setProxy(object) Sets the Proxy to use for this model. Accepts any options that can be accepted by Ext.createByAlias.
    suspendEvents(bool) Suspends the firing of all events. (see resumeEvents)
    un(JsString, Delegate, object) Shorthand for removeListener. Removes an event handler.
    unjoin(Store) Tells this model instance that it has been removed from the store.
    validate() Validates the current data against all of its configured validations.

    Fields

    Name Description
    associations An array of associations for this model.
    belongsTo One or more BelongsTo associations for this model.
    clientIdProperty The name of a property that is used for submitting this Model's unique client-side identifier to the server when multiple phantom records are saved as part of the same Operation. In such a case, the server response should include the client id for each record so that the server response data can be used to update the client-side records if necessary. This property cannot have the same name as any of this Model's fields. Defaults to: null
    defaultProxyType The string type of the default Model Proxy. Defaults to 'ajax'. Defaults to: "ajax"
    hasMany One or more HasMany associations for this model.
    idgen The id generator to use for this model. The default id generator does not generate values for the idProperty. This can be overridden at the model level to provide a custom generator for a model. The simplest form of this would be:
      Ext.define('MyApp.data.MyModel', {
                extend: 'Ext.data.Model',
                requires: ['Ext.data.SequentialIdGenerator'],
                idgen: 'sequential',
                ...
                });
                
    The above would generate sequential id's such as 1, 2, 3 etc.. Another useful id generator is Ext.data.UuidGenerator:
      Ext.define('MyApp.data.MyModel', {
                extend: 'Ext.data.Model',
                requires: ['Ext.data.UuidGenerator'],
                idgen: 'uuid',
                ...
                });
                
    An id generation can also be further configured:
      Ext.define('MyApp.data.MyModel', {
                extend: 'Ext.data.Model',
                idgen: {
                type: 'sequential',
                seed: 1000,
                prefix: 'ID_'
                }
                });
                
    The above would generate id's such as ID_1000, ID_1001, ID_1002 etc.. If multiple models share an id space, a single generator can be shared:
      Ext.define('MyApp.data.MyModelX', {
                extend: 'Ext.data.Model',
                idgen: {
                type: 'sequential',
                id: 'xy'
                }
                });
                Ext.define('MyApp.data.MyModelY', {
                extend: 'Ext.data.Model',
                idgen: {
                type: 'sequential',
                id: 'xy'
                }
                });
                
    For more complex, shared id generators, a custom generator is the best approach. See Ext.data.IdGenerator for details on creating custom id generators.
    idProperty The name of the field treated as this Model's unique id. Defaults to 'id'. Defaults to: "id"
    listeners A config object containing one or more event handlers to be added to this object during initialization. This should be a valid listeners config object as specified in the addListener example for attaching multiple handlers at once. DOM events from Ext JS Components While some Ext JS Component classes export selected DOM events (e.g. "click", "mouseover" etc), this is usually only done when extra value can be added. For example the DataView's itemclick event passing the node clicked on. To access DOM events directly from a child element of a Component, we need to specify the element option to identify the Component property to add a DOM listener to:
    new Ext.panel.Panel({
                width: 400,
                height: 200,
                dockedItems: [{
                xtype: 'toolbar'
                }],
                listeners: {
                click: {
                element: 'el', //bind to the underlying el property on the panel
                fn: function(){ console.log('click el'); }
                },
                dblclick: {
                element: 'body', //bind to the underlying body property on the panel
                fn: function(){ console.log('dblclick body'); }
                }
                }
                });
                
    persistenceProperty The name of the property on this Persistable object that its data is saved to. Defaults to 'data' (i.e: all persistable data resides in this.data.) Defaults to: "data"
    proxy The proxy to use for this model.
    validations An array of validations for this model.

    Properties

    Name Description
    COMMIT The update operation of type 'commit'. Used by Store.update event. Defaults to: "commit"
    dirty True if this Record has been modified. Defaults to: false
    EDIT The update operation of type 'edit'. Used by Store.update event. Defaults to: "edit"
    editing Internal flag used to track whether or not the model instance is currently being edited. Defaults to: false
    eventsSuspended Initial suspended call count. Incremented when suspendEvents is called, decremented when resumeEvents is called. Defaults to: 0
    fields A Collection of the fields defined for this Model (including fields defined in superclasses) This is a collection of Ext.data.Field instances, each of which encapsulates information that the field was configured with. By default, you can specify a field as simply a String, representing the name of the field, but a Field encapsulates data type, custom conversion of raw data, and a mapping property to specify by name of index, how to extract a field's value from a raw data object.
    hasListeners This object holds a key for any event that has a listener. The listener may be set directly on the instance, or on its class or a super class (via observe) or on the MVC EventBus. The values of this object are truthy (a non-zero number) and falsy (0 or undefined). They do not represent an exact count of listeners. The value for an event is truthy if the event must be fired and is falsy if there is no need to fire the event. The intended use of this property is to avoid the expense of fireEvent calls when there are no listeners. This can be particularly helpful when one would otherwise have to call fireEvent hundreds or thousands of times. It is used like this:
    if (this.hasListeners.foo) {
               this.fireEvent('foo', this, arg1);
               }
                
    isModel true in this class to identify an object as an instantiated Model, or subclass thereof. Defaults to: true
    isObservable true in this class to identify an object as an instantiated Observable, or subclass thereof. Defaults to: true
    modified Key: value pairs of all fields whose values have changed Defaults to: {}
    phantom True when the record does not yet exist in a server-side database (see setDirty). Any record which has a real database pk set as its id property is NOT a phantom -- it's real. Defaults to: false
    raw The raw data used to create this model if created via a reader.
    REJECT The update operation of type 'reject'. Used by Store.update event. Defaults to: "reject"
    store The Store to which this instance belongs. NOTE: If this instance is bound to multiple stores, this property will reference only the first. To examine all the stores, use the stores property instead.
    stores The Stores to which this instance is bound. Defaults to: []
    © Copyright 2005-2011 SharpKit. All rights reserved.