Архитектура Ext JS приложения

Ext JS поддерживает архитектуры MVC и MVVM.

Модель представляет собой слой данных. Модель может содержать валидацию данных и логику сохранения данных. В Ext JS модель используется вместе с хранилищем данных (data store).

Представление - это пользовательский интерфейс. Кнопки, формы, окна сообщений - это всё представления. 

Контроллер управляет логикой связанной с представлением, обработкой событий в представлении и любой другой логикой приложения.

ViewModel инкапсулирует логику представления, связывает данные с представлением и управляет обновлением при изменении данных.


Файл app.js содержит следующий код:
Ext.application({
    name: 'MyApp', // имя приложения 
    extend: 'MyApp.Application', // объявлен в файле app/Application.js
    requires: [ // список необходимых классов для создания экземпляра этого класса
        'MyApp.view.main.Main'
    ],
    mainView: 'MyApp.view.main.Main' // начальный вид
});

Файл app/Application.js содержит следующий код:
Ext.define('MyApp.Application', {
    extend: 'Ext.app.Application', // там определена функция launch 
    
    name: 'MyApp',

    stores: [
        // Хранилища данных
    ],
    
    launch: function () {
        // Вызывается после загрузки страницы
    },

    onAppUpdate: function () {
        Ext.Msg.confirm('Application Update', 'This application has an update, reload?',
            function (choice) {
                if (choice === 'yes') {
                    window.location.reload();
                }
            }
        );
    }
});

Файл app\view\main\MainModel.js представляет собой ViewModel класс для главного представления Main.
Ext.define('MyApp.view.main.MainModel', {
    extend: 'Ext.app.ViewModel',

    alias: 'viewmodel.main',

    data: {
        name: 'MyApp',

        loremIpsum: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
    }

    //TODO - add data, formulas and/or methods to support your view
});

В файле app\view\main\MainController.js содержится контроллер для главного представления в приложении.
Ext.define('MyApp.view.main.MainController', {
    extend: 'Ext.app.ViewController',

    alias: 'controller.main',

    onItemSelected: function (sender, record) {
        Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this);
    },

    onConfirm: function (choice) {
        if (choice === 'yes') {
            //
        }
    }
});
Функция onItemSelected вызывается при выделении элемента в таблице данных. Есть два типа контроллеров: Ext.app.ViewController и Ext.app.Controller.

Если вы создали приложение с ключом --modern (Sencha Touch) или --classic (Sencha Ext JS) то будет файл app\view\main\Main.js. Для универсального приложения будут два файла Main.js в папках \modern\src\view\main\ и \classic\src\view\main\.

Содержимое файла modern\src\view\main\Main.js.
Ext.define('MyApp.view.main.Main', {
    extend: 'Ext.tab.Panel',
    xtype: 'app-main',

    requires: [ // Зависимости:
        'Ext.MessageBox',

        'MyApp.view.main.MainController',
        'MyApp.view.main.MainModel',
        'MyApp.view.main.List'
    ],

    controller: 'main',
    viewModel: 'main',

    defaults: {
        tab: {
            iconAlign: 'top'
        },
        styleHtmlContent: true
    },

    tabBarPosition: 'bottom',

    items: [
        {
            title: 'Home',
            iconCls: 'x-fa fa-home',
            layout: 'fit',
            // The following grid shares a store with the classic version's grid as well!
            items: [{
                xtype: 'mainlist'
            }]
        },{
            title: 'Users',
            iconCls: 'x-fa fa-user',
            bind: {
                html: '{loremIpsum}'
            }
        },{
            title: 'Groups',
            iconCls: 'x-fa fa-users',
            bind: {
                html: '{loremIpsum}'
            }
        },{
            title: 'Settings',
            iconCls: 'x-fa fa-cog',
            bind: {
                html: '{loremIpsum}'
            }
        }
    ]
});

Содержимое файла classic\src\view\main\Main.js.
Ext.define('MyApp.view.main.Main', {
    extend: 'Ext.tab.Panel',
    xtype: 'app-main',

    requires: [
        'Ext.plugin.Viewport',
        'Ext.window.MessageBox',

        'MyApp.view.main.MainController',
        'MyApp.view.main.MainModel',
        'MyApp.view.main.List'
    ],

    controller: 'main',
    viewModel: 'main',

    ui: 'navigation', // нужно для responsive design

    tabBarHeaderPosition: 1,
    titleRotation: 0,
    tabRotation: 0,

    header: {
        layout: {
            align: 'stretchmax'
        },
        title: {
            bind: {
                text: '{name}'
            },
            flex: 0
        },
        iconCls: 'fa-th-list'
    },

    tabBar: {
        flex: 1,
        layout: {
            align: 'stretch',
            overflowHandler: 'none'
        }
    },

    responsiveConfig: {
        tall: {
            headerPosition: 'top'
        },
        wide: {
            headerPosition: 'left'
        }
    },

    defaults: {
        bodyPadding: 20,
        tabConfig: {
            plugins: 'responsive',
            responsiveConfig: {
                wide: {
                    iconAlign: 'left',
                    textAlign: 'left'
                },
                tall: {
                    iconAlign: 'top',
                    textAlign: 'center',
                    width: 120
                }
            }
        }
    },

    items: [{
        title: 'Home',
        iconCls: 'fa-home',
        // The following grid shares a store with the classic version's grid as well!
        items: [{
            xtype: 'mainlist'
        }]
    }, {
        title: 'Users',
        iconCls: 'fa-user',
        bind: {
            html: '{loremIpsum}'
        }
    }, {
        title: 'Groups',
        iconCls: 'fa-users',
        bind: {
            html: '{loremIpsum}'
        }
    }, {
        title: 'Settings',
        iconCls: 'fa-cog',
        bind: {
            html: '{loremIpsum}'
        }
    }]
});

Аналогично Main.js можете самостоятельно рассмотреть List.js.