iririr
iririr

Reputation: 261

router backbone.js handle events

I have a very complex Backbone application with many views/Models and collections.

at times when user clicks a button I need to update multiple collections and update certain views.

In order to manage the collections I've handled most events in my router. The sequence of events is as follows:

user clicks a link/button and view triggers an event:

 this.model.trigger('someEvent');

the model listening to the event, updates itself if necessary and notifies the router through my eventbus

eventbus.trigger('globalEVent');

My router is listening to global events, fetches collections/models from a cached storage and updates the necessary collections and models.

This has worked really well so far but

I have just too many events and my router code is becoming hard to manage. My question is there a way to handle events outside of the router and still access methods inside the router? is my approach correct or is there a more elegant solution I haven't considered?

Update:

Here's how I do it now:

in Router I call this method in my initialize():

        registerModules : function() {
           var self = this;
           Backbone.trigger(Events.RegisterModule, function(moduleRoutes) {

           _.each(moduleRoutes, function(moduleRoute) {
               self.routeDetails[moduleRoute.name] = {
                  buildPageUrl: moduleRoute.buildPageUrl,
                  fragment :  moduleRoute.fragment
               }
               self.route(moduleRoute.fragment, moduleRoute.name, moduleRoute.action);
           });

           });
        },

Then I have regular self-exec blocks for each module/page which self registers (simplified version):

(function() {

   var module = {

            loadAndDisplay: function() {},
            saveAndContinue: function(model) {

                Backbone.trigger(Events.ChangePage, model.get('nextPage'));

            },
            registerEvents: function() {},
            _init: function() {
                module.registerEvents();
                var self = this,
                    routes =  [{
                        fragment: Constants.FRAGMENT,
                        name: Constants.PAGE_NAME,
                        buildPageUrl:  function() {
                            return Constants.FRAGMENT;
                        },
                        action: module.loadAndDisplay
                    }];

                Backbone.on(Events.RegisterModule, function(registerCallback) {
                    registerCallback.call(registerCallback, routes);
                });
            }
        };

    module._init();    

})();

Of course your Router script should load before your module code. It works great for my needs. With this design I have separated router / modules completely and they have no knowledge of each other either. Each will handle it's own events/data etc. Shared logic goes in router.

Upvotes: 1

Views: 293

Answers (1)

Andreas Köberle
Andreas Köberle

Reputation: 111032

You should split you router functionality into different classes. In our Marionette based application we using a RegionManager to handle all the view related stuff, like change views in different areas, open overlays etc and a StateMachine. The router itself just trigger different events, like state:change or region:change where the manager classes listen to.

Doing it tis way, you can have a different manager classes that handle a special aspect of your app. Let the router to what he is build for: listen on location change events and notify the app about it. The router should not have other logic then this.

Upvotes: 1

Related Questions