ExtJS 4.1 Call One Controller From Another

假如想象 提交于 2019-12-03 12:55:57

问题


Note: I'm a total ignoramus regarding javascript.

I've broken my ExtJS 4.1 MVC app out into several controllers like:

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

I want to respond to an "event", not a DOM Event, rather a Ext.form.action.Submit.success event by calling functions in both my Auth and Quiz controllers. The summarized code for the first part is here:

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

This works but feels wrong. Is there a proper way to do this? It seems like I should fire a unique event that is listened to by both controllers, but I can't understand how to do that with Ext.Event. Any guidance?

Thanks! I'm really grateful for all the great ideas and advice.


回答1:


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




回答2:


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.




回答3:


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




回答4:


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




回答5:


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
...
}


来源:https://stackoverflow.com/questions/12065926/extjs-4-1-call-one-controller-from-another

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!