8

注意:我对 javascript 完全无知。

我已经将我的 ExtJS 4.1 MVC 应用程序分解为几个控制器,例如:

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

我想通过调用我和控制器中函数来响应“事件”,而不是DOM Event,而是一个事件。第一部分的总结代码在这里:Ext.form.action.Submit.successAuthQuiz

// 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. 有什么指导吗?

谢谢!我真的很感谢所有伟大的想法和建议。

4

5 回答 5

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 中成功使用了这种方法

于 2012-08-22T04:18:03.543 回答
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 的补丁以实现此目的。

于 2012-08-22T04:04:55.217 回答
2

没有标准的方法来触发控制器之间的事件,但可以通过一些自定义黑客来实现。请参阅我最近的博客文章

于 2012-08-22T03:38:24.243 回答
0

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

于 2015-10-07T08:47:28.620 回答
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
...
}
于 2015-10-07T12:50:59.680 回答