1

I'm trying to share a Marionette App with some of its Views. I've read the wiki here, but the example leaves me with a question.

I've got a file with a couple of views in it that will all need to use the request/response system and possibly the commands. I don't want to do var MyApp = require('app'); in all of the Views in the file. I came up with the following, but I think there's probably a better way to do it.

Example:

//Views.js
define( ["marionette"], function (Marionette) {
var App = function(){
    return require('app');
};

var ExampleItemView = Marionette.ItemView.extend({
    initialize: function(){
        App().request("getInfo", "aboutStuff");
    }
});

return Marionette.CollectionView.extend({
    itemView: ExampleItemView,
    initialize: function(){
        App().request("getInfo", "aboutStuff");
    }
});

Is there a better way to do this?

D_Naish
  • 543
  • 4
  • 20
  • Trigger an event that your app listens for? – fbynite Jul 27 '13 at 02:28
  • As in use a global vent like the example in the wiki? I guess that'd work, but I'm really just trying to share some high level info across the entire app without passing it down through all the views as options arguments. I'll update the code in the example. – D_Naish Jul 27 '13 at 12:22
  • I just found [link](http://stackoverflow.com/a/4881496/886877). Wonder if that will fit the bill in this case? I'll test it as soon as I can. – D_Naish Jul 27 '13 at 13:39

2 Answers2

5

I'd definitely not inject your app into your views since it can create circular dependencies which are ALWAYS a code smell (regardless of whether they can be solved or not) The simples solution by far is to create a separate (singleton) reqres object which is handled by the app and injected into the views.

//reqres.js
define(['backbone.wreqr'], function( Wreqr ){
    return new Wreqr.RequestResponse();
});

//app
define(['reqres'], function(reqres){
    reqres.setHandlers({
        'getInfo' : function(){
            return 'foo';
        }
    });
});

//Views.js
define( ["marionette", "reqres"], function (Marionette, reqres) {
var ExampleItemView = Marionette.ItemView.extend({
    initialize: function(){
        reqres.request("getInfo", "aboutStuff");
    }
});

return Marionette.CollectionView.extend({
    itemView: ExampleItemView,
    initialize: function(){
        reqres.request("getInfo", "aboutStuff");
    }
});
Creynders
  • 4,573
  • 20
  • 21
  • Doesn't my example use the same technique that the Marionette wiki (linked in OP) uses in the "Avoiding Circular Dependencies" section? – D_Naish Jul 29 '13 at 14:37
  • Also, in your example, is there a way to tie that singleton object to a specific "module" (if there are multiple "moduels" in an app) for portability between different pages? I guess the app could always require wreqr and I could just namespace the handlers for the "modules". – D_Naish Jul 29 '13 at 14:43
  • @Dustin yeah, it's the same technique for _solving_ circular deps, not **avoiding** them. And regarding modularizing the singleton: sure. You could also create a reqres singleton per module etc. Depends on what you want to do. – Creynders Jul 29 '13 at 17:14
  • That did the trick. Each of my module folders and the app folder now has a reqres.js. A module's views only know about that module's reqres and only the module definition knows about the app's reqres. Thanks! – D_Naish Jul 29 '13 at 21:02
2

Backbone Wreqr is to be replaced by Backbone Radio in the next major release of Marionette, v3.

To use Backbone Radio you could create a channel and do the following:

/**
 * App.js (for example)
 */
var Radio = require('backbone.radio');
// Use the 'data' channel - this could be whatever channel name you want
var dataChannel = Radio.channel('data');

// Handler for a request
dataChannel.reply('getMessage', function(name) {
  return 'Hello ' + name + '. Alba gu brath!';
});

/**
 * View.js (for example)
 */
var Radio = require('backbone.radio');
var dataChannel = Radio.channel('data');

// Make the request
console.log( dataChannel.request('getMessage', 'Craig') ); // -> Hello Craig. Alba gu brath!
Craig Myles
  • 5,206
  • 3
  • 40
  • 37