Hacker News new | comments | show | ask | jobs | submit login
Building a single page app with Backbone.js, underscore.js and jQuery (andyet.net)
103 points by ericflo 2637 days ago | hide | past | web | favorite | 19 comments

Nice article! I think it hits a lot of the philosophy behind rich JS Apps. Taking some key points from it:

* Do not store state in the DOM. You'll live to regret it when you need to represent the same model in more than one place at once, or refactor your UI.

* Events are the way to go, when connecting changes in the model to updates in the view. Ideally, models know nothing about what UI happens to be on the screen at any given moment.

* If you're going to be doing interesting business logic in the client, it helps to have collections (in this case, Backbone.Collection) with a richer API than JS arrays: filter, any, map, reduce, reject, include, invoke...

* Lots of little testable JS files for development, one minified gzipped file for production.

The one point I'm in disagreement with is: "Keep your models as simple as possible". In my opinion, client-side models really shine when they contain a large part of your important JS business logic, and you can use the same models in different situations to provide access-control, URL generation, data munging, etc.

For example, here's a list of some of the methods we have on a Backbone.Model called "Document": viewerUrl, publishedUrl, canonicalId, openViewer, openText, openPdf, allowedToEdit(account), checkAllowedToEdit(account, message), checkBusy, notes, uniqueEntities, isPending, isPublic, isPublished.

I can understand why storing state on the DOM would quickly start to suck if you're building a single-page application, but I've found it works really well for applications that work without JavaScript using progressive enhancement.

True, what I'm talking about in my post is definitely a different paradigm than a more traditional web site where one of the goals is to make it widely accessible for any and all users/devices.

ps. thanks for reading my post simon, u da man!

We're in agreement there -- the DOM is a nice place (technically the only place) to store state for light JS enhancement of web sites, but I think we're going to see a larger gap grow between those and web apps.

Jeremy, first of all. Thanks for Backbone! You guys rock.

I'm glad you liked my post.

Regarding "keeping models simple". Perhaps I wasn't so clear. My point here was mainly just that when I first started trying to build a model layer separate from the DOM (pre-backbone). I was very explicitly defining what attributes each model has and then also doing the corresponding DOM manipulations in my setters and getters. That got messy pretty quickly.

So, my point was not that you shouldn't add methods to your Backbone.Model's, but rather that you should keep view and controller logic out of your model layer.

Ah, great -- we agree then after all. Models contain sophisticated domain logic, but know nothing about HTML or DOM manipulation. Perhaps that point could be expanded with a bit more nuance at the end of article.

what is the best way to handle not storing state on DOM, when you need to maintain javascriptless functionality, and your data is loaded from the server pre-render? currently using data attributes to solve this. which means our state is in DOM anyway.

I'd think it'd be a little nicer to bootstrap in the data as JSON objects -- so that you don't have to scrape your own data out of the HTML...

But really, if you have to maintain JavaScript-less functionality for a web site (not a web app), that's a fine way to do it. Pull all of your data out of the data attributes once at load time, and you're off to the races.

thanks! good to know it's not atypical... it naturally doesn't "feel right". this functionality is one of the only things that has kept my code from evolving into nearly backbone. felt like maybe I was missing a piece of the puzzle.

considering that... backbone is not exactly what I need, but it is definitely inspiring for refining my own solutions (which again, are drawn from similar conclusions).

Thanks for your input. As you probably realized, my post was more about a strategy for apps that feel more like desktop apps, where once you're logged in, you're not really moving around from page to page at all. In my case it was a chat app where the whole app was useless without JS.

It's an interesting thought, though. However, I don't know if I'd see the need for something like backbone on any site where I was trying to support non-js browsers.

"Also, since JavaScript has no formal classes there is no self-evident approach for structuring an entire application."

Really? http://javascript.crockford.com/prototypal.html

Please don't just quote Crockford as gospel truth.

Crockford's prototypal revelation is only a slight alteration of the standard constructor pattern, and not a particularly useful one. You still have a class (the object that serves as a prototype for every instance you create), it doesn't add any particular flexibility, and it's quite slow. I encourage you to run the tests yourself:


For me, that test clocks using Crockford's pattern to instantiate objects as 80% slower in Safari and Firefox, and 95% slower in Chrome, when compared to a standard use of JS prototypes.

Care to explain what you mean? Given that...

- Crockford originally thought it worthwhile to emulate classical inheritance

- so many, many other frameworks (and technique essays) provide various flavors of class-based inheritance

and that:

- even embracing true prototypical inheritance requires additional helper functions (or at least did in EcmaScript 3)

...I'm a little confused that you disagree that "there is no self-evident approach" for dealing with JavaScript's 'conflicted' (as the linked article correctly states) way of being a so-called prototypical language.

hi, i've been experimenting a bunch with different approaches to doing MVC in Javascript. I did one project where I completely rolled my own rails-like framework, with a base controller, base model & view functionality based on EJS (my favorite js templating library).

Then I discovered sammy.js, which provides a nice approach to routing and linking. my current project uses that, and i roll my own data access code & use EJS for templating. I also have written all my own glue.

The space is calling out for a "Javascript on Rails" that takes a variety of different libraries and combines them in a canonical way so that each new project doesn't have to go through a shopping expedition, deciding which libraries are currently the best.

What's needed, basically:

1. Routing, navigation + back-button. Single-page JS apps operate very differently from normal apps because many links are hash links, eg. #settings. Sammy.js handles this nicely.

2. models. Here I have a different definition of what a model is than Backbone. I see a model as a class that wraps a particular service. So you might have a TwitterModel, YouTubeModel, MyServiceModel, etc. They would all benefit from inheriting from a base class that does the necessary networking (JSONP, JSON, etc.). It would be nice if all data came back from the service in the form of a Backbone.js Collection.

3. Views. There is a lot of code that ends up being needed around rendering templates. Think of the variety of different render() functions that exist in rails. That translates to Javascript, in my experience. Rendering templates into a div, doing pre- and post- processing, even swapping rendered blocks into invisible divs so they can be swapped back in quickly when the user hits the back button.

I could go on about the neat things that could/should be done, including all the declarative programming and "convention over configuration" stuff that rails does (example: render_foo() loads template foo.ejs and renders it into <div id='foo'>)

Anyway I feel myself a bit lost in a sea of googling whenever I try to find the definitive projects in this space - so I hope some will comment with their fave MVC-esque projects for Javascript...

Sammy.js does look quite cool. I've poked around the documentation, but haven't built anything with it yet.

I see what you're saying about "Javascript on Rails" but to me that's quite different than something like backbone. What you're talking about is more about "ajaxifying" a traditional browse-from-page-to-page experience. I definitely think there's value in that for improving the feel and responsiveness of a site. However, I'm more interested in truly emulating the desktop app experience where, once you log in there is no concept of browsing from page to page or "going back".

Have you seen Qooxdoo? I've made some very desktop-like apps with it http://demo.qooxdoo.org/current/showcase/#form

There's a ticket that proposes adding a "hashchange" router to Backbone, if you're interested in contributing your thoughts:


The big question is if it's useful enough -- Models/Collections/Views are used constantly, whereas hashchange routing is a comparatively tiny part of an app. For the record, the previous Backbone+Sammy discussion is here:


And there's another on the Sammy list:


Why use hash tags? HTML5 has support for altering the URL without leaving the page and adding new entries in the browser history.

Sounds like a better than the age-old hashtag workaround.

Was there a demo for this app you built? i couldn't find a link

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact