Класс модуля

Средний

Объявить класс модуля 

Объявление классов — функция JavaScript-фреймворка ExtJS. Чтобы объявить класс, используйте стандартный механизм библиотеки — метод define() глобального объекта Ext.

Пример объявления класса с помощью метода define()
/* Название класса с использованием пространства имен. */ 
Ext.define("Terrasoft.configuration.ExampleClass", {
    /* Сокращенное название класса. */
    alternateClassName: "Terrasoft.ExampleClass",
    /* Название класса, который наследует текущий класс. */
    extend: "Terrasoft.BaseClass",
    /* Конфигурационный объект, который содержит объявления статических свойств и методов. */
    static: {
        /* Пример статического свойства. */
        myStaticProperty: true,

        /* Пример статического метода. */
        getMyStaticProperty: function () {
            /* Пример доступа к статическому свойству. */
            return Terrasoft.ExampleClass.myStaticProperty;
        }
    },
    /* Пример динамического свойства. */
    myProperty: 12,
    /* Пример динамического метода класса. */
    getMyProperty: function () {
        return this.myProperty;
    }
});

Примеры создания экземпляров класса представлены ниже.

/* Создает экземпляр класса с использованием полного названия. */
var exampleObject = Ext.create("Terrasoft.configuration.ExampleClass");
/* Создает экземпляр класса с использованием сокращенного названия — алиаса. */
var exampleObject = Ext.create("Terrasoft.ExampleClass");

Наследовать класс модуля 

В большинстве случаев класс модуля необходимо наследовать от классов BaseModule или BaseSchemaModule пространства имен Terrasoft.configuration.

Методы, которые предоставляют классы BaseModule и BaseSchemaModule:

  • init() — реализует логику, которая выполняется при загрузке модуля. При загрузке модуля клиентское ядро автоматически вызывает этот метод первым. Как правило, в методе init() выполняется подписка на события других модулей и инициализация значений.
  • render(renderTo) — реализует логику визуализации модуля. При загрузке модуля клиентское ядро автоматически вызывает этот метод. Для корректного отображения данных перед их визуализацией должен отработать механизм связывания представления (View) и модели представления (ViewModel). Поэтому, как правило, в методе render() выполняется запуск механизма — вызов у объекта представления метода bind(). Если модуль загружается в контейнер, то в качестве аргумента метода render() передается ссылка на этот контейнер. Метод render() обязателен для визуальных модулей.
  • destroy() — отвечает за удаление представления модуля, удаление модели представления, отписку от ранее подписанных сообщений и удаление объекта класса модуля.

Пример класса модуля, который наследуется от класса Terrasoft.BaseModule, приведен ниже. Модуль добавляет кнопку в DOM. При нажатии на кнопку выводится сообщение, после этого кнопка удаляется из DOM.

Пример класса модуля, который наследуется от класса Terrasoft.BaseModule
define("ModuleExample", [], function () {
    Ext.define("Terrasoft.configuration.ModuleExample", {
        /* Сокращенное название класса. */
        alternateClassName: "Terrasoft.ModuleExample",
        /* Название класса, который наследует текущий класс. */
        extend: "Terrasoft.BaseModule",
        /* Обязательное свойство. Если не задано, то генерируется ошибка на уровне Terrasoft.core.BaseObject, поскольку класс наследует класс Terrasoft.BaseModule. */
        Ext: null,
        /* Обязательное свойство. Если не задано, то генерируется ошибка на уровне Terrasoft.core.BaseObject, поскольку класс наследует класс Terrasoft.BaseModule. */
        sandbox: null,
        /* Обязательное свойство. Если не задано, то генерируется ошибка на уровне Terrasoft.core.BaseObject, поскольку класс наследует класс Terrasoft.BaseModule. */
        Terrasoft: null,
        /* Модель представления. */
        viewModel: null,
        /* Представление. В качестве примера используется кнопка. */
        view: null,
        /* Если не реализовать метод init() в текущем классе, то при создании экземпляра текущего класса вызывается метод init() родительского класса Terrasoft.BaseModule. */
        init: function () {
            /* Вызывает выполнение логики метода init() родительского класса. */
            this.callParent(arguments);
            this.initViewModel();
        },
        /* Инициализирует модель представления. */
        initViewModel: function () {
            /* Сохраняет контекст класса модуля для доступа к нему из модели представления. */
            var self = this;
            /* Создает модель представления. */
            this.viewModel = Ext.create("Terrasoft.BaseViewModel", {
                values: {
                    /* Заголовок кнопки. */
                    captionBtn: "Click Me"
                },
                methods: {
                    /* Обработчик нажатия на кнопку. */
                    onClickBtn: function () {
                        var captionBtn = this.get("captionBtn");
                        alert(captionBtn + " button was pressed");
                        /* Вызывает метод выгрузки представления и модели представления для удаления кнопки из DOM. */
                        self.destroy();
                    }
                }
            });
        },
        /* Создает представление (кнопку), связывает ее с моделью представления и добавляет в DOM. */
        render: function (renderTo) {
            /* Создает кнопку в качестве представления. */
            this.view = this.Ext.create("Terrasoft.Button", {
                /* Контейнер, в который добавляется кнопка. */
                renderTo: renderTo,
                /* HTML-атрибут id. */
                id: "example-btn",
                /* Название класса. */
                className: "Terrasoft.Button",
                /* Заголовок. */
                caption: {
                    /* Связывает заголовок кнопки со свойством captionBtn модели представления. */
                    bindTo: "captionBtn"
                },
                /* Метод-обработчик события нажатия на кнопку. */
                click: {
                    /* Связывает обработчик события нажатия на кнопку с методом onClickBtn() модели представления. */
                    bindTo: "onClickBtn"
                },
                /* Стиль кнопки. */
                style: this.Terrasoft.controls.ButtonEnums.style.GREEN
            });
            /* Связывает представление и модель представления. */
            this.view.bind(this.viewModel);
            /* Возвращает представление, которое добавлено в DOM. */
            return this.view;
        },
        /* Удаляет неиспользуемые объекты. */
        destroy: function () {
            /* Удаляет представление для удаления кнопки из DOM. */
            this.view.destroy();
            /* Удаляет неиспользуемую модель представления. */
            this.viewModel.destroy();
        }
    });
    /* Возвращает объект модуля. */
    return Terrasoft.ModuleExample;
});

Переопределить члены класса модуля 

При наследовании класса модуля в классе-наследнике можно переопределить публичные и приватные свойства и методы базового модуля.

Приватные свойства или методы класса — свойства или методы, названия которых начинаются с символа нижнего подчеркивания, например, _privateMemberName.

Назначение отслеживания — при объявлении пользовательского класса проверять выполнение переопределений приватных свойств или методов, которые объявлены в родительских классах. Консоль браузера отображает предупреждение о переопределении в режиме отладки. Подробнее читайте в статье Front-end отладка.

Чтобы отслеживать переопределение приватных членов класса модуля, используйте класс Terrasoft.PrivateMemberWatcher.

Например, в пользовательский пакет добавлена схема модуля UsrPrivateMemberWatcher.

UsrPrivateMemberWatcher
define("UsrPrivateMemberWatcher", [], function() {
    Ext.define("Terrasoft.A", {_a: 1});
    Ext.define("Terrasoft.B", {extend: "Terrasoft.A"});
    Ext.define("Terrasoft.MC", {_b: 1});
    Ext.define("Terrasoft.C", {extend: "Terrasoft.B", mixins: {ma: "Terrasoft.MC"}});
    Ext.define("Terrasoft.MD", {_c: 1});
    /* Переопределяет свойство _a. */
    Ext.define("Terrasoft.D", {extend: "Terrasoft.C", _a: 3, mixins: {mb: "Terrasoft.MD"}});
    /* Переопределяет свойство _с. */
    Ext.define("Terrasoft.E", {extend: "Terrasoft.D", _c: 3});
    /* Переопределяет свойства _a и _b. */
    Ext.define("Terrasoft.F", {extend: "Terrasoft.E", _b: 3, _a: 0});
});

После загрузки модуля UsrPrivateMemberWatcher консоль браузера отобразит предупреждение о переопределении приватных членов базовых классов.

scr_result.png

Инициализировать экземпляр класса модуля 

Способы инициализации экземпляра класса модуля:

  • Синхронная инициализация.
  • Асинхронная инициализация.

Инициализировать экземпляр класса модуля синхронно 

Модуль инициализируется синхронно, если при его загрузке явно не указано свойство isAsync: true конфигурационного объекта, который передается в качестве параметра метода loadModule(). Например, методы класса модуля загружаются синхронно при выполнении кода, который приведен ниже.

this.sandbox.loadModule([moduleName])

Первым вызывается метод init(), затем — метод render().

Пример реализации синхронно инициализируемого модуля
define("ModuleExample", [], function () {
    Ext.define("Terrasoft.configuration.ModuleExample", {
        alternateClassName: "Terrasoft.ModuleExample",
        Ext: null,
        sandbox: null,
        Terrasoft: null,
        init: function () {
            /* Выполняется первым при инициализации модуля. */
        },
        render: function (renderTo) {
            /* Выполняется после метода init() при инициализации модуля. */
        }
    });
});

Инициализировать экземпляр класса модуля асинхронно 

Модуль инициализируется асинхронно, если при его загрузке явно указано свойство isAsync: true конфигурационного объекта, который передается в качестве параметра метода loadModule(). Например, методы класса модуля загружаются асинхронно при выполнении кода, который приведен ниже.

this.sandbox.loadModule([moduleName], { 
    isAsync: true 
})

Первым вызывается метод init(). В качестве параметра метода init() передается callback-функция с контекстом текущего модуля. При вызове callback-функции вызывается метод render() загружаемого модуля. Представление добавляется в DOM только после выполнения метода render().

Пример реализации асинхронно инициализируемого модуля
define("ModuleExample", [], function () {
    Ext.define("Terrasoft.configuration.ModuleExample", {
        alternateClassName: "Terrasoft.ModuleExample",
        Ext: null,
        sandbox: null,
        Terrasoft: null,
        /* Выполняется первым при инициализации модуля. */
        init: function (callback) {
            setTimeout(callback, 2000);
        },
        render: function (renderTo) {
            /* Выполняется c задержкой в 2 секунды, которая указана в параметре функции setTimeout() метода init(). */
        }
    });
});

Цепочки модулей 

Цепочки модулей — механизм, который позволяет отобразить представление одной модели на месте представления другой модели. Например, чтобы установить значение поля на текущей странице, необходимо отобразить страницу SelectData, которая позволяет выбрать значение из справочника. То есть, на месте контейнера модуля текущей страницы отобразить представление модуля страницы выбора из справочника.

Чтобы построить цепочку, добавьте свойство keepAlive в конфигурационный объект загружаемого модуля.

Пример вызова модуля selectDataModule, который позволяет выбрать значение из справочника, в модуле текущей страницы CardModule приведен ниже.

Пример вызова одного модуля из другого модуля
sandbox.loadModule("selectDataModule", {
    /* Id представления загружаемого модуля. */
    id: "selectDataModule_id",
    /* Представление добавляется в контейнер текущей страницы. */
    renderTo: "cardModuleContainer",
    /* Указывает, чтобы текущий модуль не выгружался. */
    keepAlive: true
});

После выполнения кода строится цепочка из модуля текущей страницы и модуля страницы выбора из справочника. Если добавить в цепочку еще один элемент, то из модуля текущей страницы selectData по нажатию на кнопку Добавить новую запись (Add new record) откроется новая страница. Количество модулей, которые можно добавлять в цепочку, не ограничено.

Активный модуль — последний элемент цепочки, который отображается на странице. Если в качестве активного модуля установить модуль из середины цепочки, то удаляются все элементы, которые находятся в цепочке после активного. Чтобы активировать модуль в цепочке, передайте идентификатор модуля в качестве параметра функции loadModule().

Пример вызова функции loadModule()
sandbox.loadModule("someModule", {
    id: "someModuleId"
});

Ядро удалит элементы цепочки, после чего вызовет методы init() и render(). В метод render() передается контейнер, который содержит предыдущий активный модуль. Нахождение модуля в цепочке не влияет на его работу.

Если при вызове метода loadModule() в конфигурационный объект не добавлять свойство keepAlive или добавить его со значением keepAlive: false, то цепочка модулей удаляется.

Смотрите также