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.
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.
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...
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.
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:
- Crockford originally thought it worthwhile to emulate classical inheritance
- so many, many other frameworks (and technique essays) provide various flavors of class-based inheritance
- even embracing true prototypical inheritance requires additional helper functions (or at least did in EcmaScript 3)
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.
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.
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'>)
Sammy.js does look quite cool. I've poked around the documentation, but haven't built anything with it yet.
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: