Using Browserify with Backbone projects, and I'm just wondering if anyone's got any advice/pointers on how to handle global state. By global state, I don't necessarily mean global variables, but I mean values that are application-wide, ie. currently logged in user, the app router (for navigating from Views), an Events object (for communication around the application).
Apart from passing these things into each View/module that might need them, is there a simpler way?
If we use Backbone as a working example, I have code like:
signupComplete: function() {
swap(regions.content, new views.completeSignup({
model: this.currentUser(),
router: this
}));
},
this lives in my app-router.js
and as you can see, it's passing the router itself into the instantiated View.
Is this kind of practice recommended in CommonJS style applications, where dependencies are kept local and "global" is advised against.
Not sure if there's a right answer here, just looking for some different approaches people have taken in this, relatively, young concept in building client-side applications with Browserify...
How about a singleton pattern type of thing?
var router;
module.exports = function () {
if (!router) router = new Router();
return router;
};
Here's an approach that avoids the boilerplate of passing state down view trees, but still gives the option for local state for testing or sub-systems. TL;DR: sling it on View.prototype, override via constructor where necessary.
In views (and views are the only place I see this as necessary) we access the user via this.user
, which will be from the prototype unless an instance is passed an user in the constructor.
var View = Backbone.View.extend({
constructor: function(opts) {
if(opts.user) this.user = opts.user;
if(opts.vent) this.vent = opts.vent;
Backbone.View.apply(this,arguments);
}
});
In a production boot script we pass any app-wide state to the prototype:
var user = new User;
var vent = new Vent;
View.prototype.user = user;
View.prototype.vent = vent;
In some sub-system with a local version of any of these bits of state, pass it in and it'll be used in preference to the prototype property:
var subVent = new Vent;
var subA = new SomeView({name: "subA",vent: subVent});
var subB = new SomeView({name: "subB",vent: subVent});
In testing:
var mockVent = new Vent;
toTest = new SomeView({name: "testA",vent: mockVent});
Here's a live demo of the technique.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With