Waiting for Ext JS 4: Data Package

Original author: Ed Spencer
  • Transfer
From the translator: We offer you the second article from the series “Pending Ext JS 4”. In a previous article , Ext JS developers talked about the new class system.

The data package is responsible for receiving, decoding and using information in your application. It is one of those parts of the library, which accounted for the greatest number of improvements and additions.

The package has been completely rewritten for the fourth branch of the framework, but the general concept has not changed since the previous versions. Today we will become more familiar with this technology and look at its capabilities.

What's new


The package works with data in Ext JS 4 consists of 43 classes, but three of them are particularly important in comparison with the rest - this model (Model), Storage (Store) and proxy (Proxy). They are used in almost every application along with satellite classes.



Models and Repositories



The basic element of the package is the Ext.data.Model class, which is responsible for working with the model. A model is a set of certain data in an application - for example, in an electronic store there may be models for Users, Products, and Orders.

In the most simplified version, the Model is a set of fields and their values. Anyone working with Ext JS 3 probably used the Ext.data.Record class, the predecessor of Ext.data.Model. Let's see how we are creating the model now:

Ext.regModel('User', {
    fields: [
        {name: 'id', type: 'int'},
        {name: 'name', type: 'string'}
    ]
});


Typically, Models are used in conjunction with Repositories - sets of Model instances. Declaring the Warehouse and loading data into it is simple:

new Ext.data.Store({
    model: 'User',
    proxy: {
        type: 'ajax',
        url : 'users.json',
        reader: 'json'
    },
    autoLoad: true
});


That's all that needs to be done in order to download a set of instances of the Users model from the address 'users.json'. We configured our Warehouse using AjaxProxy to read data at the specified address and the Ext.data.Reader class to transcode the data. In our case, the server returns the response in JSON format, which is why we prepared JsonReader to read the response.

Using the Storage, you can sort, filter and group data both locally and remotely. The fourth version of Ext JS lacks a separate GroupingStore class, since the standard Storage is suitable for multiple sorting, filtering and grouping of records:

new Ext.data.Store({
    model: 'User',
    sorters: ['name', 'id'],
    filters: {
        property: 'name',
        value   : 'Ed'
    },
    groupers: {
        property : 'age',
        direction: 'ASC'
    }
});


In the Warehouse we just created, the data will be sorted first by name (field name), and then by field id; records will be filtered so that only Users with the name 'Ed' are left and grouped by age (age field). If required, you can easily change the sorting, filtering, or grouping options at any time using the Store API.

Proxies


Above, we saw how the Repository uses Proxies to load data and how Proxies can be configured to use Reader classes to parse the server response. Compared to the third version, there is one structural change in Ext JS 4: The repository no longer contains references to the Reader and Writer classes that have been ported to Proxies. This approach provides us with an incredible advantage - Proxies can now be specified directly in the Model:

Ext.regModel('User', {
    fields: ['id', 'name', 'age'],
    proxy: {
        type: 'rest',
        url : '/users',
        reader: {
            type: 'json',
            root: 'users'
        }
    }
});
//используем прокси модели
new Ext.data.Store({
    model: 'User'
});


We have a double win: firstly, it is very likely that each Repository that works with the Users model loads data the same way - accordingly, we do not have to duplicate the Proxy descriptions for the Repositories. Secondly, we can now load and save a model instance without Storage:

//получаем ссылку на класс Пользователя (User)
var User = Ext.getModel('User');
var ed = new User({
    name: 'Ed Spencer',
    age : 25
});
//Мы можем сохранить Эда напрямую, без добавления его в Хранилище
//потому что мы настроили специальный тип Прокси - RestProxy, который автоматически
// пошлет POST запрос на изменение данных по адресу /users
ed.save({
    success: function(ed) {
        console.log("Saved Ed! His ID is "+ ed.getId());
    }
});
//Загружаем Пользователя 123 и что-то с ним делаем (по факту вызывается GET-запрос /users/123)
User.load(123, {
    success: function(user) {
        console.log("Loaded user 123: " + user.get('name'));
    }
});


We also bring to your attention several new types of Proxies that use the capabilities of HTML 5 - LocalStorageProxy and SessionStorageProxy. Although older browsers do not support HTML 5 innovations, the new Proxies are so useful that many applications will benefit from their use. Even if we do not have a proxy that meets your requirements, then you can simply create your own.

Communications


Proxies are not the only new features added to Models. Now you can define relationships between Models using the new Associations API. Most applications work with a serious number of different Models, and Models are usually interconnected at the level of applied logic. A blog platform can have models for Users, Posts, and Comments. Each User publishes Records, and the Record receives Comments. We can describe the relationships between the models as follows:

Ext.regModel('User', {
    fields: ['id', 'name'],
    hasMany: 'Posts'
});
Ext.regModel('Post', {
    fields: ['id', 'user_id', 'title', 'body'],
    belongsTo: 'User',
    hasMany: 'Comments'
});
Ext.regModel('Comment', {
    fields: ['id', 'post_id', 'name', 'message'],
    belongsTo: 'Post'
});


The task of describing the relationships between different models is not too complicated. Each model can contain descriptions of any number of relationships with other models, and the models themselves can be declared in any order. After receiving an instance of the model, we can track the associated data - for example, if we want to receive a log of all the Comments to the Records that a certain User left, then the following construction can be used:

//Получаем пользователя с ID 123 при помощи Прокси модели User
User.load(123, {
    success: function(user) {
        console.log("User: " + user.get('name'));
        user.posts().each(function(post) {
            console.log("Comments for post: " + post.get('title'));
            post.comments().each(function(comment) {
                console.log(comment.get('message'));
            });
        });
    }
});


Each of the many-to-one relationships (hasMany) turns into a new function that is added to the Model. We indicate that each User has many Records. This relationship is described in the user.posts () function, which we met in the previous code fragment. A call to this function will return the Vault configured to work with the Records model. In turn, the Notes model has a comments () function, because a many-to-one relationship with the Comments model is specified.

Perhaps you were surprised by the fact why we set the 'success' handler to call User.load, but we do not do this while accessing the User’s posts and comments. It is believed that all data is downloaded asynchronously from a remote server. This fact implies the use of special success-handlers, which are automatically called at the time of the final and successful data loading - as a function described above.

Download related data


The library can automatically recognize and process related data in one request, based on the described relationships between the models. Instead of first requesting data for the User, then about the Record, and even upon request for each Comment, we can return all the necessary information in one server response:

{
    id: 1
    name: 'Ed',
    posts: [
        {
            id   : 12,
            title: 'All about data in Ext JS 4',
            body : 'One of the areas that has seen the most improvement in Ext JS 4...',
            comments: [
                {
                    id: 123,
                    name: 'S Jobs',
                    message: 'One more thing'
                }
            ]
        }
    ]
}


You can easily configure Proxy models to receive data from any source, and Reader classes will help to cope with the most intricate response formats. Starting with Ext JS 3, Models and Repositories are widely used by components within the framework, in particular - Tables (Grids), Trees (Tress) and Forms (Forms).

Opportunity demonstration


We have prepared a small online demo for you . This application uses the same Models that were described in the article, but the code processes the test data. You can also download the demo in one archive and experiment yourself. The library itself is now in beta, so errors can sometimes occur, but overall the data processing package is quite stable.

To learn more news from the world of Sencha Touch and Ext JS, I suggest you subscribe to our monthly newsletter , which usually contains articles that you will not find anywhere else (even on our blog).

Also popular now: