tl;dr: When moving from page to page, change/destroy only these blocks that need it (not re-rendering whole page). And keep application router as simple as possible.
I'm new to backbone and all of the examples to get started with it that I've seen were about small apps with a single page that changes a little sometimes (adding/removing some elements, but never completely re-rendering). But when I started doing my app which is a little bit more complex, I faced the problem of subviews organization...
Problem: When every page of application consists of subviews (each subview can have another subviews, ie nested subviews), which are responsible for displaying their blocks in the page, a reasonable desire would be not to re-render blocks that not changing when you're navigating through pages. Sometimes you need to re-render whole page, when it's completely different from previous, sometimes just some blocks on the page. But in this case application router becomes monster-object that contains too much logic, so that it's hard to maintain.
What I want: I want my router to be like
define(['jquery', 'backbone'], function ($, Backbone) {
return Backbone.Router.extend({
routes: {
"": "home",
..........
},
home: function () {
require(['views/home'], function (View) {
var view = new View({ el: $("body") });
view.render();
});
},
..........
});
});
So, my goal is to move logic for rendering subviews to views. So that view will decide what to do: render itself including subviews or just ask subviews to decide same question for themselves.
Possible solution: Thinking about it I come with idea of global object that contains tree of views as application state (e.g. first_design(home(about, login)) ). And when we're moving to next page, that has the same main view (ie first_design) we don't render first_design view, but just it's subviews (in this case only home). And for every page in router we now need to manually define this tree of views. For example like this:
define(['jquery', 'backbone'], function ($, Backbone) {
return Backbone.Router.extend({
routes: {
"": "home",
"contacts": "contacts",
..........
},
home: function () {
require(['views/firstDesign', 'views/home', 'views/about', 'views/login'], function (FirstDesign, Home, About, Login) {
new FirstDesign({ el: $("body"), subviews: { new Home({ subviews: { new About(), new Login() } }) } });
});
},
contacts: function () {
require(['views/firstDesign', 'views/contacts'], function (FirstDesign, Contacts) {
new FirstDesign({ el: $("body"), subviews: { new Contacts() } });
});
},
..........
});
});
So, the question is...: I believe i'm reinventing the wheel right now and obviously my wheel is not good enough (possibly even not round :D). So are there any implementations of what I need? Or if not, then how I should do it properly? Thanks!
P.S: I'm using backbone.js with require.js. And sorry for my English, it's not my native language...