In the previous chapter, we built an MVC architecture-based application from scratch. We looked at the different classes the Ext JS and Sencha Touch frameworks offer, which helped us model our application as per the MVC architecture.
In Ext JS, the following classes constitute the implementation of an MVC architecture:
However, in Sencha Touch, the following classes constitute the implementation of an MVC architecture:
In this chapter, we will look into the detail of each of these classes, which act as the building blocks for creating applications. We will look at the function of each class and the behaviors they support.
Model represents a state of the application and helps share the state across various views in an application. It typically contains the fields to store data/state and knows how to persist itself through the data package. In the previous chapters, we defined two models—Department
and User
. Each one of them had fields
which represented the entity, either Department
or User
.
The model related code is kind of common across Ext JS and Touch frameworks. Their internal implementations differ on each of these frameworks. However, the interface remains consistent. We will highlight the differences wherever applicable.
In the estjsapp
applications, we defined the following models:
Ext.define('AM.model.Department', { extend: 'Ext.data.Model', fields: ['code', 'name', 'location'] }); Ext.define('AM.model.User', { extend: 'Ext.data.Model', fields: ['id', 'name', 'email', 'department'] });
In the touchapp
applications, we defined the following models:
Ext.define('AM.model.Department', { extend: 'Ext.data.Model', config: { fields: ['code', 'name', 'location'] } }); Ext.define('AM.model.User', { extend: 'Ext.data.Model', config: { fields: ['id', 'name', 'email', 'department'] } });
Apart from the usage of config
in Touch, the definitions are pretty much the same.
Every model must extend Ext.data.Model
and must at least have the fields
defined. A model class offers the following:
fields
, which allows us to list out the attributes of an entity, for example, e-mail
of an user
.presence
, length
, inclusion
, exclusion
, and format
. And, if needed, we can also define additional validation types and use them to validate the data inside a model; for example, presence
can help us to validate if name is present on the model or not. For this, the model has got a validations config property where we list out the different validations that we would like to apply on the model instance. After the validations are configured, the validate()
method on a model instance must be called to validate that instance using the specified validations
list. More details about it are available on the documentation of the Ext.data.Model
class. Chapter 5, Dealing with Data and Data Sources of Sencha Touch Cookbook, Packt Publishing, also discusses this in detail and provides additional recipes to define a custom validation.Department
and the User
model so that in a single load of the JSON file, both the Department
and their User
models are created and are ready for use. There are two types of associations the framework supports—hasMany
(one-to-many) and belongsTo
(many-to-one). So, we may say a Department
has many User
models and that a User
belongs to a Department
. More detail about it is available in the documentation of the Ext.data.Model
class.proxy
to connect to a data source. A proxy is a way to connect to a data source and operate on that to create, read, update, and destroy. In our example, we did not configure the proxy on the model. Rather, we configured it on the store. However, if needed, a proxy can also be specified on a model.The following operations can be performed on a model instance:
load
: This loads a model from a data source using the proxy
configuration.save
: This saves a model to a data source using the proxy
configuration. If the id
field is empty, the create
request is sent to the data source. Otherwise, the update
request is sent.erase
: This destroys a model using the configured proxy. This does not destroy the model instance on the client side. After the data source returns success, it notifies the store, which it is joined to, and the store takes care of removing that model instance from the client side.reject
: This is used by the store usually to revert the changes made to the model instance during the editing, for example, the e-mail ID is changed as part of the user edit.commit
: This commits the changes to the mode instance since either the creation or the last commit operation. This does not send the data to the data source.validate
: This validates the model instance against all the configured validations. This returns an array of errors containing the field and the message for all the fields that did not pass the validation.destroy
: This destroys the model instance from the client side. To destroy a model instance from the data source, one must use the erase
operation, as discussed previously.copy
: This helps us create a copy of an existing model instance. The ID of the new model can either be specified while calling this method or the framework will automatically generate it.A model can very well participate in the editing operation and can help us keep track of the changes. The following operations can be performed on a model instance as part of editing:
beginEdit
: This marks the beginning of the editing of the model. This can, loosely, be compared with transaction start.endEdit
: This marks the end of the editing. It can, loosely, be compared with transaction end.cancelEdit
: This allows us to cancel any edits made to the model instance after beginEdit
. This can, loosely, be compared with transaction rollback.changedWhileEditing
: This helps us to check if the underlying model instance has changed during an edit.getChanges
: This helps us to get the list of fields whose values have changed during the edit operation. In Ext JS framework, the method name is getModifiedFieldNames
.isModified
: This helps us to check if a particular field value has changed in the model instance.The operations mentioned previously notify the stores, based on which the store updates itself and notifies the view of the change.
Store contains a collection of models and can be specified on various components to help them present the data in their own unique way.
In the estjsapp
applications, this is how we defined a store:
Ext.define('AM.store.Departments', { extend: 'Ext.data.Store', model: 'AM.model.Department', autoLoad: true, proxy: { type: 'ajax', api: { read: 'data/departments.json' }, reader: { type: 'json', root: 'departments', successProperty: 'success' } } });
In the touchapp
applications, this is how we defined a store:
Ext.define('AM.store.Departments', { extend: 'Ext.data.Store', alias: 'store.Departments', config: { autoLoad: true, model: 'AM.model.Department', storeId: 'Departments', proxy: { type: 'ajax', api: { read: 'data/departments.json' }, reader: { type: 'json', rootProperty: 'departments' } } } });
Again, besides the config
usage in the Touch, the two definitions are the same. Every store must be an instance of Ext.data.Store
and can contain the models that are of the type, Ext.data.Model
.
A store class offers the following:
fields
, which allows us to list out the attributes of an entity, for example, the e-mail of an user.store
definition, we specified ajax
as the kind of proxy that we would be using. This selection is based on the kind of data source that we are dealing with. read
is the URL used by the proxy to read data. The reader
instance converts the data read from the data source to a model instance. Similar to read, we can specify URLs for other CRUD operations that the proxy supports.autoLoad
: This allows us to indicate whether the data shall be loaded immediately after the store is initialized by the framework or an explicit load
method will be called to initiate the loading. true
indicates automatic loading.autoSync
: This allows us to indicate whether the modifications to the store models shall be synched up automatically, or if an explicit sync
call will be called. Value true
indicates automatic sync.Following operations can be performed on a store
instance:
For any change to the data collection, the store notifies the view, which is associated with it so that the views can show the updated data.
3.142.40.32