ExtJS 4.1 Вызов Одного Контроллера Из Другого

Примечание: я полный невежда в отношении javascript.

Я разбил приложение ExtJS 4.1 MVC на несколько контроллеров, таких как:

/app/controller/Auth
    |          |Quiz
    |          |Result
    |          |Blah...
    |model/...

Я хочу ответить на "событие", а не событие DOM, а Ext.form.action.Submit.success событие путем вызова функции и мой Auth и Quiz контроллеры. Обобщенный код для первой части находится здесь:

// File: app/controller/Auth.js
attemptLogin : function() {
    var form = Ext.ComponentQuery.query('#loginpanel')[0].form;
    if (form.isValid()) {
        form.submit({
        success : function(form, action) {
            // THIS IS THE FUNCTION FROM THE CURRENT CONTROLLER
            Assessor.controller.Auth.prototype.finishLogin();
            // THIS IS THE FUNCTION FROM THE OTHER CONTROLLER
            Assessor.controller.Quiz.prototype.setupAssessment();
        },

это работает, но неправильно. Есть ли правильный способ сделать это? Кажется, я должен запустить уникальное событие, которое прослушивается обоими контроллерами, но я не могу понять, как это сделать с Ext.Event. Каких-либо указаний?

спасибо! я очень благодарен за все замечательные идеи и советы.

5 ответов


для меня имеет смысл запускать пользовательское событие из формы и просто слушать его в обоих ваших контроллерах, как то, что вы сказали здесь:

кажется, я должен запустить уникальное событие, которое слушают оба контроллеры

// File: app/controller/Auth.js
attemptLogin : function() {
    var form = Ext.ComponentQuery.down('#loginpanel').form;
    if (form.isValid()) {
        form.submit({
        success : function(form, action) {
            // fire the event from the form panel
            form.owner.fireEvent('loginsuccess', form.owner);
        },

тогда в каждом из ваших контроллеров вы can слушайте его с помощью контроллера#control, например:

Ext.define('YourApp.controller.Auth', {
    extend: 'Ext.app.Controller',

    init: function() {
        var me = this; 

        me.control({

            '#loginpanel': {

                loginsuccess: me.someHandler

            }
        });
    },

    someHandler: function(form) {
        //whatever needs to be done
        console.log(form);
    }
}

и затем добавьте то же самое в свой Quiz контроллер:

Ext.define('YourApp.controller.Quiz', {
    extend: 'Ext.app.Controller',

    init: function() {
        var me = this; 

        me.control({

            '#loginpanel': {

                loginsuccess: me.someOtherHandler

            }
        });
    },

    someOtherHandler: function(form) {
        //whatever needs to be done
        console.log(form);
    }
}

Я успешно использовал этот подход в 4.1.0 и 4.1.1


это действительно должно быть

Assessor.controller.Auth.prototype.finishLogin.apply(this, arguments)

или что-то в этом роде (чтобы иметь правильный this ссылка, указывающая на "владельца" метода, объект контроллера)

однако, почему вы используете этот неортодоксальный способ вызова метода текущего контроллера. Просто установите scope для обратного вызова успеха, затем вызовите это.finishLogin ().

form.submit({
    success : function(form, action) {
        // THIS IS THE FUNCTION FROM THE CURRENT CONTROLLER
        this.finishLogin();
        ...
    },
    scope: this
});

кроме того, вы можете получить другой экземпляр контроллера, используя Controller#getController.

this.getController('Assessor.controller.quiz').setupAssignment();

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

другое решение-запустить пользовательское событие после завершения входа в систему. Вы можете сделать это на объекте приложения

this.application.fireEvent('logincomplete');

и в методе init контроллера:

this.application.mon('logincomplete', this.setupAssignment, this);

обратите внимание, что вы не можете слушать эти события через Controller#control - Александр Токарев блога для патч Ext для достижения этого.


нет стандартного способа запуска событий между контроллерами, но это возможно с помощью некоторых пользовательских хаков. Смотрите мой недавний блоге.


Я также искал это, и все, что вам нужно, это Асанда.приложение.getController ("викторина").setupAssignment ();, где Asanda-это имя вашего приложения


вы должны использовать MessageBus, если вам нужно отправлять события между контроллерами:

Ext.define('MyApp.utils.MessageBus', {
        extend : 'Ext.util.Observable'
});

сохраните шину сообщений в глобальном var

MsgBus = Ext.create('MyApp.utils.MessageBus');

куда вы должны отправить события:

MsgBus.fireEvent('eventName',eventArg_1,eventArg_2);

где вы должны получать события:

MsgBus.on('eventName', functionHandler,scope); //scope is not mandatory
...
functionHandler:function(eventArg_1,eventArg_2){
...
//do whatever you want
...
}