Use and function of the new Ext.app.EventDomain

2019-05-14 15:41发布

问题:

We have a huge amount of applications which all are sharing some parts (data/backend/frontend). Users may have access to one or more applications and currently the user need to load them one by one. Our Customer don't like this so we are now refactoring all into one huge application where the client itself resolves which module to load. First test looked good and due to our custom modulebuilder tool the loading times are at a min.

Now I stumbled over the new Ext.app.EventDomain and wondered if we should implement it into our refactoring cause one tricky part are the events. We also have the consideration of using routing on the table. But this debate is still going.

So should we use Ext.app.EventDomain and if so how is it used or should we better stay with a custom routing?

I mean Sencha Touch is using routing but no EventBus and I would say that Sencha Touch is performance critical so it seems there is a reason why both frameworks are differ here?

回答1:

Ext.app.EventDomain is not intended to be used per se; rather, you can implement custom event domains if you need them. The idea behind event domains is quite simple: it's a way to pass events between application parts that happen not to be Ext.Component-derived.

The most frequent use is Controller binding: in 4.1 it was only possible to call other Controllers' methods directly (hard binding), which is very bad for testing. In 4.2 you can have a Controller listen to other Controllers' events instead (soft binding) and have clear logic separation, so instead of:

Ext.define('MyApp.controller.Foo', {
    extend: 'Ext.app.Controller',

    doSomething: function() {
        this.getController('Bar').doSomethingElse();
    }
});

Ext.define('MyApp.controller.Bar', {
    extend: 'Ext.app.Controller',

    doSomethingElse: function() {
        // The problem here is that this logic belongs to Bar controller
        // but this method has to be called from Foo controller,
        // which means Bar should always be around whenever Foo
        // needs to call it. Race conditions, anyone?
        ...
    }
});

You can do:

Ext.define('MyApp.controller.Foo', {
    extend: 'Ext.app.Controller',

    doSomething: function() {
        this.fireEvent('doSomethingElse');
    }
});

Ext.define('MyApp.controller.Bar', {
    extend: 'Ext.app.Controller',

    init: function() {
        this.listen({
            controller: {
                '*': {        // '*' means any controller
                    doSomethingElse: this.doSomethingElse
                }
            }
        });
    },

    doSomethingElse: function() {
        // Not a problem anymore -- Foo fires an event, and if Bar
        // happens to be around, it reacts and does whatever it wants;
        // the benefit is that there is no direct method calling
        // so we don't have to watch for exceptions and do other
        // unnecessary stuff.
        ...
    }
});

It's also ok to listen to your own events -- which is not something you'd probably use in production but is a nice side effect that can be used very successfully for controller unit testing.

Besides other Controllers' events, a Controller can now listen to Store, Direct provider and global events, which may be useful at times.

I plan to write up on this when 4.2 is released; hope this helps a bit until then.