backbone.js - working with the event dispatcher va

2020-06-16 03:17发布

问题:

In backbone.js documentation it says:

To make a handy event dispatcher that can coordinate events among different areas of your application: var dispatcher = _.clone(Backbone.Events)

Can anyone explain how to implement the dispatcher to communicate from one view to another? Where do I have to place the code in my app?

回答1:

Here is a good article about using an event aggregator.

Can anyone explain how to implement the dispatcher to communicate from one view to another? Where do I have to place the code in my app?

You will probably have some kind of App Controller object, which will control the flow of the app, creating views, models, etc. This is also a good place for the event aggregator.

From my point of view, I think that article explains it pretty well.



回答2:

Recently I needed an EventDispatcher to handle a large amount of events without loosing track of their names and their behave.

Perhaps it helps you too.

Here a simple example View:

define(['backbone', 'underscore', 'eventDispatcher'], 
    function(Backbone, _, dispatcher){

        new (Backbone.View.extend(_.extend({
            el: $('#anyViewOrWhatever'),
            initialize: function () {
                window.addEventListener('resize', function () {
                    // trigger event
                    dispatcher.global.windowResize.trigger();
                });

                // create listener
                dispatcher.server.connect(this, this.doSomething);

                // listen only once
                dispatcher.server.connect.once(this, this.doSomething);

                // remove listener:
                dispatcher.server.connect.off(this, this.doSomething);
                // remove all listener dispatcher.server.connect from this:
                dispatcher.server.connect.off(null, this);
                // remove all listener dispatcher.server.connect with this method:
                dispatcher.server.connect.off(this.doSomething);
                // remove all listener dispatcher.server.connect no matter what and where:
                dispatcher.server.connect.off();

                // do the same with a whole category
                dispatcher.server.off(/* ... */);

                // listen to all server events
                dispatcher.server.all(this, this.eventWatcher);

            },
            doSomething: function(){

            },
            eventWatcher: function(eventName){

            }

        })
    ))();
});

Here the EventDispatcher with some example events. The events itself are predefined in the template Object. Your IDE should recognize them and lead you through the list.

As you can see, the Dispatcher run on its own. Only your View or whatever needs underlying Event methods from Backbone.

// module eventDispatcher
define(['backbone', 'underscore'], function (Backbone, _) {

    var instance;
    function getInstance () {
        if ( !instance ) {
            instance = createInstance();
        }
        return instance;
    }
    return getInstance();

    function createInstance () {
        // dummy function for your ide, will be overwritten
        function e (eventContext, callback) {}
        var eventHandler = {},

            // feel free to put the template in another module
            // or even more split them in one for each area
            template = {
                server: {
                    connect: e,
                    disconnect: e,
                    login: e,
                    logout: e
                },
                global: {
                    windowResize: e,
                    gameStart: e
                },
                someOtherArea: {
                    hideAll: e
                }
            };

        // Create Events
        _.each(template, function (events, category) {
            var handler = eventHandler[category] = _.extend({}, Backbone.Events);
            var categoryEvents = {
                // turn off listener from <category>.<**all events**> with given _this or callback or both:
                // off() complete purge of category and all its events.
                // off(callback) turn off all with given callback, no matter what this is
                // off(null, this) turn off all with given this, no matter what callback is
                // off(callback, this) turn off all with given callback and this
                off: function (callback, _this) {
                    if(!callback && _this){
                        handler.off();
                    }else{
                        _.each(template[category], function(v, k){
                            k != 'off' && template[category][k].off(callback, _this);
                        });
                    }
                }
            };
            events.all = e;
            _.each(events, function (value, event) {
                // create new Listener <event> in <category>
                // e.g.: template.global.onSomething(this, fn);
                categoryEvents[event] = function (_this, callback) {
                    _this.listenTo(handler, event, callback);
                };
                // create new Listener <event> in <category> for only one trigger
                // e.g.: template.global.onSomething(this, fn);
                categoryEvents[event].once = function (_this, callback) {
                    _this.listenToOnce(handler, event, callback);
                };
                // trigger listener
                // e.g.: template.global.onSomething.trigger();
                categoryEvents[event].trigger = function (debugData) {
                    console.log('**Event** ' + category + '.' + event, debugData ? debugData : '');
                    handler.trigger(event);
                };
                // turn off listener from <category>.<event> with given _this or callback or both:
                // off() complete purge of category.event
                // off(callback) turn off all with given callback, no matter what this is
                // off(null, this) turn off all with given this, no matter what callback is
                // off(callback, this) turn off all with given callback and this
                // e.g.: template.global.onSomething.off(fn, this);
                categoryEvents[event].off = function (callback, _this) {
                    handler.off(event, callback, _this);
                }

            });
            template[category] = categoryEvents;
        });

        return template;
    }

});

The behavior of Backbones Event-system is not affected in any way and can be used as normal.