Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js - Routers, view rendering and general conceptualizations

Tags:

backbone.js

I've done a fair bit of introductory tutorial reading (including Absolute Beginners, Learn it Completely, and large parts of the 2 Code School Backbone courses) and I can completely see the potential that Backbone offers. But the comprehension light bulb hasn't quite turned on yet...I think the vast majority of examples being simple todo apps makes it seem a lot more trivial than it actually is when working on more complex projects.

My experiments have gone ok to a point - but I think getting answers or feedback about the following series of scattershot questions now might save me a lot of frustration and move me up the learning curve towards where I'd like to be. I've tried to include relevant snippets for examples that are of a detailed nature.

1) Routers are awesome, but are / are not the place for any heavy lifting?

The following router works to move user from initial page load into a specific route (search) which has its SearchBoxView instantiated in the last js loaded similar to app.js in the TodoMVC example. However trying to setup the views in router as shown for SummaryResultsView generates an 'is not a constructor' error.

var Workspace = Backbone.Router.extend({
    routes: {
        '': 'default',
        'search': 'searchBox',
        'summary': 'summary',
        'detail': 'detail',
    },

    default: function() {
        console.log("Router: Default");
        track.Router.navigate("#search", { 
            trigger: true,
            replace: true
        });
    },

    searchBox: function () {
        console.log("Router: Search");
    },

    summary: function () {
        console.log("Router: Summary");
        new track.SummaryResultsView({ el: $("#summary #results")});
    },

I JUST found https://github.com/thomasdavis/backbonetutorials/blob/gh-pages/examples/modular-backbone/js/router.js which seems to have the router initialize behaving in a similar fashion to what I'd expect. Will try that approach next.

2) Do you have to a main page view that builds a lot of state logic in render?

What I was aiming for with the router above is that each route will have a number of views that show / hide or change their presentation based on results in the collection. Setting up what views to render on state change seemed like a good place. The TodoMVC example has the app.js view render function does a lot of the equivalent logic.

3) Underscore Templates in external files w/o require.js

I'm pretty sure I'll get to including require.js eventually - but to simplify part of the learning curve wanted to start without it. Also b/c the templates will be pulling field titles from a separate CMS and not (yet) sure how nice it will play with AMD.

4) Can it help reduce plugin dependencies like colorbox and datatables?

One of the proof of concept items I'm working towards with Backbone is a smedium-sized app that has a fair amount of presentation code written explicitly to work with these jQuery plugins. It isn't bad persay, but it seems like writing similar functionality in backbone structure would be a bit more maintainable or at least legible to understand what it is doing. Mind you, I found backbone tablesorter (out of links for post) in my travels and can't (yet) tell if it would result in any more or less tightly coupled code w.r.t plugin.

Thanks!

like image 505
Idealien Avatar asked Mar 08 '13 22:03

Idealien


1 Answers

Routers

Sure they can be used for heavy lifting - I am sure you've heard it before, but Backbone just provides the bare-bones to built on-top of as you choose.

I would set the SummaryResultsView to a variable on the Workspace router. Otherwise whenever you call Workspace.summary() you will have ghost views hanging around.

I am not sure what you are doing with track.Router.navigate as it looks like it shares the same route #search as that defined in your Workspace router, which would cause both routes to be called.

You could always create multiple routers to help you divide your code up between different sections of your application. Starting with a main router and having child routers is usually what I try and aim for.

Main Page Views

Again, some people like doing it this way and others like to kick things off from a router. If you find you have a massive main view, try splitting it into smaller views so that you Don't Repeat Yourself.

Caching views can be useful - so on a main view that is only created once (on your application start) you could do:

var MyView = Backbone.View.extend({
    childView: null,

    toggleChildView: function() {
        if (this.childView) {
          this.childView.toggle(); //Toggle show/hide
        } else {
          this.childView = new ChildView({model: someModel});
        }
    }
});

Underscore Templates

I actually found that using require.js helped me learn. It certainly helps when the application starts to grow in size - there is a require.js implementation of the TodoMVC app - if you didn't already know.

You won't be able to use external templates without the require.js (text plugin) as it uses an AJAX call to grab the template files. Unless of course you design your own AJAX call to pull in the template files but it seems like a rather long-winded way to go about it.

Template files are static - I don't fully understand how you mean pulling from a separate CMS?

Just for a side note - if you use the require.js optimization it actually in-lines your templates so they are included in one fat JS file.

Porting code

If you figure out a very generic Backbone model that works with the jQuery plugins (I have one for a jQuery UI date picker) you can pretty easily port it between applications without too much fuss. This is sped up if using require.js as its already in a separate file (copy and paste FTW).

Hope this helps!

like image 125
Hzmy Avatar answered Oct 20 '22 16:10

Hzmy