16

I have a number of backbone models, organized in collections and connected to their corresponding views and/or collections of views. Some of these models that do not belong to the same collection need to trigger an event which is of interest to another model (and maybe more than one).

The recommended way to deal with this is, I think, the "global event dispatcher/aggregator" as described here and other places.

However, I also happen to be using require.js, which seems to go against the idea of attaching the dispatcher/aggregator to the application's namespace object -- or am I wrong here?

So my question is: using require.js how can I have a number of different backbone models trigger an event that will be handled by another model?

alearg
  • 685
  • 7
  • 17

2 Answers2

35

A similar solution to what @Andreas proposed but without Backbone.Marionette (heavily inspired nonetheless, see the article linked in the question).

All you have to do is to define a module that creates a singleton of an event listener and require this object in the modules where you want to trigger an event or listen to this event.

Let's say you have app/channel.js defining your channel

define(['backbone', 'underscore'], function (Backbone, _) {
    var channel = _.extend({}, Backbone.Events); 
    return channel;
});

You can then use it as a listener via

require(['app/channel'], function (channel) {
    channel.on('app.event', function () {
        console.log('app.event');
    });
});

and you can trigger an event on this channel via

require(['app/channel'], function (channel) {
    channel.trigger('app.event');
});
nikoshr
  • 32,926
  • 33
  • 91
  • 105
  • I think that this is what I've been looking for. Thanks a lot nikoshr and andreas – alearg Sep 14 '12 at 08:08
  • What is the advantage of event usage in this situation? We still have to include "app/model" in all modules where we going to trigger that event. Why not to make an api call on that model? – vovacodes Oct 01 '13 at 13:42
  • 1
    @wizardzloy The only module you have to include is `app/channel` where you want to listen to or trigger a global event. `app/model` is only there to demonstrate a sample usage. – nikoshr Oct 01 '13 at 13:47
  • @wizardzloy But I admit the examples might be confusing. I tried to reword my answer a bit, I hope it's clearer. – nikoshr Oct 01 '13 at 13:53
  • @nikoshr But if we won't include the "app/model" that script won't be loaded at all. So we still have to include it somewhere – vovacodes Oct 01 '13 at 13:59
  • @wizardzloy You lost me. The question was about a global event handler and I hope my answer does address that. `app/model` was used as a (contrived and not very useful, indeed) demo and is now removed. – nikoshr Oct 01 '13 at 14:07
  • 2
    I think you should include underscore as well to get access to _.extend. – Aldo Feb 11 '14 at 16:14
1

We using Marionettes app.vent (which is the global event transmitter for our application), allong with require js and it works really well.

app

define(, function(){
  return new Backbone.Marionette.Application();
})

Model1

define(['app'], function(app){
  return Backbone.Marionette.Model.extend({
    initialize: function(){
      this.bindTo('app.vent', 'create:model2', this.toSomething, this);
    }
  })
})

Model2

define(['app'], function(app){
  return Backbone.Marionette.Model.extend({
    initialize: function(){
      app.vent.trigger('create:model2', this);
    }
  })
})
Andreas Köberle
  • 106,652
  • 57
  • 273
  • 297
  • Good to know that Marionette is OK with require.js. However is there no solution to the problem that doesn't involve an additional / alternative framework? – alearg Sep 13 '12 at 10:05
  • There are a bunch of solutions. I can advice PubSubJS: https://github.com/mroderick/PubSubJS – Andreas Köberle Sep 13 '12 at 10:08
  • Thanks for your suggestion, I'll have a look at it. But are there no solutions that do not involve _any_ additional framework? – alearg Sep 13 '12 at 11:02
  • There is no such thing in requirejs, so you have to use an additional framework or write by yourself. – Andreas Köberle Sep 13 '12 at 11:04