ExtJS 4.1 Call One Controller From Another

南楼画角 提交于 2019-12-03 03:10:59

It makes sense to me to fire a custom event from the form and simply listen to it in both your controllers, like what you said here:

It seems like I should fire a unique event that is listened to by both controllers

// 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);
        },

Then in each of your controllers you can listen to it with Controller#control, like this:

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);
    }
}

And then add the same thing to your Quiz controller:

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);
    }
}

I've used this approach successfully in 4.1.0 and 4.1.1

It really should be

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

or something along these lines (in order to have a correct this reference that points to the 'owner' of the method, the controller object)

However, why do you use this unorthodox way to call the current controller's method. Just set the scope for the success callback, then call this.finishLogin().

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

Also, you can retrieve another controller instance using Controller#getController.

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

Then, if your controller methods are not depending on each other, you could make them both listen to the same event.

Another solution is to fire a custom event once the login is finished. You could do that on the application object

this.application.fireEvent('logincomplete');

and in your controller's init method:

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

Please note that you cannot listen to those events via Controller#control - see Alexander Tokarev's blog post for a patch to Ext to achieve this.

There is no standard way to fire events between controllers, but it's possible with some custom hacks. See my recent blog post.

I have also been looking for this and all you need is Asanda.app.getController('quiz').setupAssignment();, where Asanda is the name of your app

You should use a MessageBus if you have to send events between controllers:

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

store the message bus in a global var

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

Where you have to send events:

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

Where you have to receive events:

MsgBus.on('eventName', functionHandler,scope); //scope is not mandatory
...
functionHandler:function(eventArg_1,eventArg_2){
...
//do whatever you want
...
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!