I am separating my views and router into separate files with require. I then have a main.js file that instantiates the router, and also renders my default view.
My r
In case anyone else is looking for a solution to this problem like I was, I'm posting what I ended up doing. If you're using the boilerplate backbone.js, then you will have an initialize()
function in router.js
. I modified my initialize()
function to look like the following:
initialize = function () {
var app_router;
app_router = new AppRouter();
// Extend the View class to include a navigation method goTo
Backbone.View.goTo = function (loc) {
app_router.navigate(loc, true);
};
Backbone.history.start();
};
Due to backbone.js's particular flavour of inheritance, this allows allows me to call MyView.goTo(location);
from within any of my views.
What about this approach? As backbone implements the template pattern in all its 4 components, with a little of design you can provide to each view an easy navigation mechanism through the app's router without needing to make any circular reference (this was something I saw in other similar posts, but try to avoid it).
Router component, not to much different from other router examples:
define('Router', ['backbone', ... ],
function (Backbone, ...) {
var MyRouter = Backbone.Router.extend({
routes: {
'viewA': 'viewA',
'viewB': 'viewB'
},
initialize: function () {
...
};
},
viewA: function () {
...
},
viewB: function () {
...
}
});
return MyRouter;
});
App, creates the router instance and fires the first view passing this instance:
define('App', ['backbone', ...
], function (Backbone, ...) {
function initialize() {
//route creation
if (!this.routes)
routes = new Router(this);
//backbone history start
Backbone.history.start();
//ViewA navigation, bigbang
if (!this.viewA)
this.viewA = new ViewA({router: this.routes});
this.viewA.render();
}
return {
initialize: initialize
};
});
BaseView, base constructor definition for all views and also a navigation method:
define('BaseView', ['jquery', 'underscore', 'backbone', ...
], function ($, _, Backbone, ...) {
var BaseView;
BaseView = Backbone.View.extend({
id: '...',
constructor: function (options) {
this.router = options.router;
this.model = options.model;
Backbone.View.prototype.constructor.call(this);
},
initialize: function () {
this.template = _.template(tpl);
},
events: {
},
render: function () {
$(this.el).html(this.template());
return this;
},
//Provides transparent navigation between views throught the backbonejs
//route mechanism
navigate: function(pageId)
{
this.router.navigate(pageId, {trigger: true});
}
});
return BaseView;
});
A View instance, each view extends from the base one instead of backbone, and inherits base behavior:
define('ViewA', ['jquery', 'underscore', 'backbone', 'BaseView'
], function ($, _, Backbone, BaseView) {
var ViewA;
ViewA = BaseView.extend({
id: '...',
constructor: function (options) {
this._super("constructor");
},
...
foo: function()
{
...
this.navigate("viewB");
}
});
return ViewA;
});
It works for me, and also it can be reuse in other projects.