Skip to content

Instantly share code, notes, and snippets.

@squarism
Created February 20, 2012 19:30
Show Gist options
  • Save squarism/1870892 to your computer and use it in GitHub Desktop.
Save squarism/1870892 to your computer and use it in GitHub Desktop.
backbone noob
(function($) {
// i hate globals too but this is all that works
window.Album = new (Backbone.Model.extend({
defaults: {
foo: "bar"
}
}));
})(jQuery);
// in console
JSON.stringify(new Album());
// => "{"foo":"bar"}"
// would like to namespace this? this is what I'm confused about from your post
(function($) {
var album = new (Backbone.Model.extend({
defaults: {
foo: "bar"
}
}));
})();
// in console again
JSON.stringify(new Album());
// => ReferenceError: Album is not defined
JSON.stringify(new album());
// => ReferenceError: album is not defined
JSON.stringify(album);
// => ReferenceError: album is not defined
@ngauthier
Copy link

Yep, that's the point! You can't access the stuff in the closure outside the closure. So, you need to define everything inside the closure.

$(function() {
  var Album = Backbone.Model.extend({/* ... */})
  var AlbumView = Backbone.View.extend({/* ... */})

  var album = new Album({/* */});
  var albumView = (new AlbumView({el: $('#albumview')})).render()
});

Now, clearly that makes no sense for larger apps, because you want to split up your files (even though we'll concat them to package anyways!).

So, my rule of thumb is:

Declare classes in a namespace on window, never instances.

So, feel free to:

window.MyApp.Album = Backbone.Model.extend({ /* */})

$(function() {
  // instances are not accessible outside this closure
  var mainAlbum = new window.MyApp.Album();
  var mainAlbumView = new window.MyApp.AlbumView({el: $('#mainAlbumView'), model: mainAlbum});
}

remember global variables are bad. Emphasis on the variable part. So instances are variable, but classes are not.

The main thing this prevents is a common shortcut like referencing window.AlbumsCollection inside a view. Views can have collections passed in during their instantiation, do that!

You should have lots of class files, then one "bootstrap" method inside a jquery onReady closure where you instantiate all your objects and kickstart the app. From then on, the objects should only have references to each other internally, never via a global accessor.

This means that your code can easily be ported or embedded alongside additional code. For example, what if you wanted two main album views? If you use global variables you're screwed. But if you dependency inject variables in a closure, it's easy as pie.

xoxo @ngauthier

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment