I am confused how I should implement namespacing in Backbone.js. I have been creating my Models, Collections & Views globally. Is namespacing them simply adding a App.
infront of the models, collections and views classes & objects, and a line window.App = {};
?
It appears to work, but is this way considered a best practice? If not, what would be a better approach?
I have also seen App = App || {};
somewhere. What is the purpose of having || {}
?
Attempt at Namespacing // Namespace window.App = {};
// Models
App.Product = Backbone.Model.extend();
// Collections
App.ProductCollection = Backbone.Collection.extend({
model: App.Product,
url: '/wizard'
});
// Views
App.ProductListView = Backbone.View.extend({
el: '#photo_list',
initialize: function() {
this.collection.bind('reset', this.render, this);
},
render: function() {
this.collection.each(function(product, index){
$(this.el).append(new App.ProductView({ model: product }).render().el);
}, this);
return this;
}
});
// Snippet
App.productList = new App.ProductCollection();
App.selectedProductList = new App.SelectedProductCollection();
App.productListView = new App.ProductListView({ collection: App.productList });
I am confused how I should implement namespacing in Backbone.js. I have been creating my Models, Collections & Views globally. Is namespacing them simply adding a App.
infront of the models, collections and views classes & objects, and a line window.App = {};
?
It appears to work, but is this way considered a best practice? If not, what would be a better approach?
I have also seen App = App || {};
somewhere. What is the purpose of having || {}
?
Attempt at Namespacing // Namespace window.App = {};
// Models
App.Product = Backbone.Model.extend();
// Collections
App.ProductCollection = Backbone.Collection.extend({
model: App.Product,
url: '/wizard'
});
// Views
App.ProductListView = Backbone.View.extend({
el: '#photo_list',
initialize: function() {
this.collection.bind('reset', this.render, this);
},
render: function() {
this.collection.each(function(product, index){
$(this.el).append(new App.ProductView({ model: product }).render().el);
}, this);
return this;
}
});
// Snippet
App.productList = new App.ProductCollection();
App.selectedProductList = new App.SelectedProductCollection();
App.productListView = new App.ProductListView({ collection: App.productList });
App = App || {}
basically says "if App
is undefined
, create an empty object."
– ahren
Commented
Sep 3, 2012 at 3:55
You're better off using a namespace function which will create or update a namespaced object, e.g. ns('App.Views.Homepage', Backbone.View.extend({...})
.
Re. namespacing convention - for your own convenience you can use your file system structure. For example, UI/Homepage/View/Main.js
will bee App.UI.Homepage.View.Main
(this is if you use modules).
Or another easy way to make is simple and easy to find relevant files - create structure based on functionality, e.g. App.Backbone.Collection.Comments
, where you go from more general to more specific, e.g. you have one app, one Backbone, where you have Views, Models, Collections, Routers. And inside each you will have multiple modules specific to your use case.
As an example, here's a namespace function I use:
var ns = window.ns = function (nspace, payload, context) {
payload = payload || {};
context = context || window;
var parts = nspace.split('.'),
parent = context,
currentPart = '';
while (currentPart = parts.shift()) {
if (parts.length !== 0) {
parent[currentPart] = parent[currentPart] || {};
}
else {
parent[currentPart] = parent[currentPart] || payload;
}
parent = parent[currentPart];
}
return parent;
Use is as I mentioned above.
JavaScript does not support namespaces. Your approach amounts to nesting your backbone objects inside of a global App object. This is about as close as you will get to namespacing in JavaScript. See ahren's ment with regards to the initializer syntax.
App = App || {};
- does the following. If App is undefined (not initialized, used first time) || operator returns false
so, second statement applied and App variable is initialized with empty object.