ExtJS 4.1从另一个调用一个控制器

时间:2012-08-22 03:24:22

标签: events extjs controller

注意:关于javascript,我总是无知。

我将ExtJS 4.1 MVC应用程序分成几个控制器,如:

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

我想通过调用中的函数来回复“事件”,而不是 DOM事件,而不是Ext.form.action.Submit.success事件我的{{1} }和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(); }, 来执行此操作。有什么指导吗?

谢谢!我非常感谢所有伟大的想法和建议。

5 个答案:

答案 0 :(得分:6)

从表单中激活自定义事件并在控制器中单独收听它就像我在这里说的那样:

  

似乎我应该触发两个人都听过的独特事件   控制器

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

然后在每个控制器中,可以使用Controller#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

中成功使用了这种方法

答案 1 :(得分:3)

真的应该是

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

或沿着这些行的某些内容(为了有一个正确的this引用指向方法的“所有者”,控制器对象)

但是,为什么使用这种非正统的方式来调用当前控制器的方法。只需为成功回调设置scope,然后调用this.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收听这些活动 - 请参阅Alexander Tokarev的博文,了解Ext的补丁以实现此目的。

答案 2 :(得分:2)

没有标准方法可以在控制器之间触发事件,但是可以使用一些自定义黑客攻击。请参阅我最近的blog post

答案 3 :(得分:0)

我一直在寻找这个,你需要的只是Asanda.app.getController('quiz')。setupAssignment();,其中Asanda是你的应用程序的名称

答案 4 :(得分:0)

如果必须在控制器之间发送事件,则应使用MessageBus:

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

将消息总线存储在全局变量

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