

Backbone patterns - VMG
http://ricostacruz.com/backbone-patterns

======
conesus
One of the patterns looks like it requires more processing power than
necessary. The rendering of a template should be fast, since you will likely
be doing it many times on a page.

    
    
        ContactView = Backbone.View.extend({
          template: function() {
            var template = _.template($("#template-contact").html());
            return template.apply(this, arguments);
          },
    
          render: function() {
            // This is a dictionary object of the attributes of the models.
            // => { name: "Jason", email: "j.smith@gmail.com" }
            var dict = this.model.toJSON();
    
            // Pass this object onto the template function.
            // This returns an HTML string.
            var html = this.template(dict);
    
            // Append the result to the view's element.
            $(this.el).append(html);
    
            // ...
          }
        })
    

Note that the template is already on the page and has to be serialized by
jQuery with the `_.template($("#template-contact").html());` line. It would be
faster to already have the template in a JavaScript string, ready to be
interpolated with your values.

Otherwise, for every view you will be fetching the template from the DOM. The
difference in implementation would be from this:

    
    
      <div id="template-contact">Mail me at <%= email %></div>
    

to this:

    
    
      <script>var templateContact = "Mail me at <%= email %>"</script>
    

It's a bit more work, but it reduces the amount of work that has to happen
just to render one of many templates.

~~~
rstacruz
I think a simpler way would be to cache the value of
`_.template($().html());`.

------
pdelgallego
It looks great.

If anyone want to see a rails-backbone application example Railscasts has
published today "Backbone on rails part 1"[1].

[1] <http://railscasts.com/episodes/323-backbone-on-rails-part-1>

PS It's a paid screencast, but railscasts pro is worth the money.

------
jugglinmike
It's great to see knowledge like this compiled into one place. Unfortunately,
it looks like the resource is only superficially open source.

I was about to make a pull request to fix a typo, when I found someone had
already done so: <https://github.com/rstacruz/backbone-patterns/pull/3>

If a objective correction like this takes 6 weeks (and counting!) to be
merged, does the open nature of this page really matter?

Not that this detracts from the message, but take the claim "This is a massive
work-in-progress." with a grain of salt.

~~~
VMG
The last commit is the January 29th, I guess he just didn't notice the pull
request

------
cfontes
Nice... I am writing my first site using backbone and as a Java Dev sometimes
I have a hard time to do things in backbone, I want to make everything a into
reusable objects and views as far as I am seeing right now are not always to
be used like that.

Sometimes They are used to listen to collections and create smaller things(
like a factory ) sometimes they can represent a whole small popup, sometimes a
single HTML entity. I am sure my code is not 100% yet, but patterns like this
help a lot.

~~~
alinajaf
Not sure why you're being downvoted, but I tend to agree. I've found that my
backbone apps are a lot nicer to deal with when I think of my views as
potentially re-usable components.

It takes a bit of forethought but you end up with much nicer, composable
interfaces that allow you to respond quickly to changing requirements.

------
andrew_wc_brown
I know in the javascript world there's a preference by large to use
camelCasing but I'm not a fan of it. I don't think its easier to read, and
there can be confusion with what to capitalize.

Also whats the purpose of putting your templates inline? I compile all my
templates server side into a js file called template.js and when I need a
template I simply call:

Template.documents.index

------
robinduckett
Notice how this carefully doesn't use silent: true, seeing as in the latest
version of Backbone, they have repurposed the silent option for completely
different functionality.

~~~
jashkenas
Not quite. (Although you and I have certainly discussed this plenty on
GitHub.) For folks who haven't been following along:

Performing "silent" changes to a model are a power-user feature of Backbone,
where you can twiddle attributes on a model temporarily, or many times,
without receiving change events. Then, when you're ready, you get a single
change event with the diff in model state.

Prior to 0.9, you'd get the single diff, but not all of the individual
"change:attribute" events for the diff. 0.9 and above have been improved to
give you both. Yes, it's something to watch out for if you want to upgrade an
existing app.

~~~
robinduckett
The problem is your complete unwillingness to compromise and to make it easier
for people to upgrade an existing app.

The way that silent works now should be it's own option, say "defer". Because
you're deferring the changes until a later date. It could even be called delay
or later. Whatever it is called, it is in no way silent anymore.

My proposal is to add a new option, mute, which bypasses the change events and
causes the attribute to change but does not trigger change:attribute.

Edit: <https://github.com/documentcloud/backbone/pull/981>

~~~
jashkenas
While I appreciate the effort and persistence, having {silent: true, mute:
true} be part of the model API is definitely _not_ the direction that the
Backbone API should be going.

That said, what you do with your copy of backbone.js in your own project is
your business. I'd highly encourage you to extend your version with your
preferred behavior for "silent" -- in fact, the source is annotated to make
this sort of thing easier for folks that find the need.

------
littlejim84
This is nice to have it in one place, but I still not sure I like
bootstrapping model data that way. Does anyone else find it a bit messy? Also,
I'm using AMD/Require.js throughout my Backbone apps, so how could I bootstrap
the model data in that manner, and still have access to it inside my modules?

~~~
jashkenas
So, the reason why you want to bootstrap the models you need for an initial
render, directly into the page ... instead of doing this:

    
    
        myApp.init = function() {
          Books.fetch();
          Authors.fetch();
          Notes.fetch();
          ...
        };
    

... is because, all else being equal, it will noticeably improve the speed of
your initial page load. Instead of N separate HTTP requests, all of your model
data is available in the same HTTP request that fetches the HTML. Put the
bootstrap at the bottom of your page, and you're in pretty good shape.

~~~
fooandbarify
Depending on the other content of the page and the nature of your traffic/user
data, it might make more sense to take advantage of caching by making the
initial loaded resource (the HTML file) completely static and loading the
bootstrapped data in a single separate request.

~~~
jashkenas
Yes, absolutely. If the initial HTML page is heavy, and can be cached for all
users, then separate makes sense. If the initial HTML page is light, or user-
specific (the usual case for a backbone app) then bootstrapping in a single
HTTP request makes sense.

------
boyter
Im still walking the backbone path so this is pretty useful.

Im curious how one would setup a instant search using it? I have done it
previously by attaching a jQuery keyup event listener but I know I should be
using a view. I have had a poke on google for this but haven't turned up
anything.

------
75c84fb8
I'd like to nominate private subviews as a pattern.

    
    
        (function(){
            var myPrivateView = Backbone.View.extend({...});
            app.views.Foo = Backbone.View.extend({
                /* use myPrivateView somewhere in here */
            });
        })();

~~~
rstacruz
Interesting. Any concrete examples of how it can be useful in a real-world
project?

~~~
75c84fb8
It's a good way to break a view into logical sub-components, while still only
exposing one overall view to the world. Really just a variation on data hiding
and encapsulation.

------
herge
I have a hard time seeing the advantages of backbone.js over something simpler
like knockout.js. Is it that good? Is it a question of having a complicated
enough webapp?

~~~
conesus
Just look at the examples of what was built using Backbone.js vs. Knockout.js.
<http://backbonejs.org/#examples> vs. <http://knockoutjs.com/examples/>.
Backbone.js has many more real-world examples that demonstrate it's
flexibility and ease.

~~~
Lazare
Those aren't really comparable links.

The Backbone link goes to a "who is using Backbone" page. Which is nice, and
quite convincing that Backbone is a serious library used in some huge
projects.

The Knockout link, however, goes to a "how do you use Knockout" page. Which is
also nice, and a very useful documentation source that Backbone is sadly
lacking.

But as a new developer, if anything, the Knockout link is a better reason to
pick it. Good documentation goes a LOT further than knowing that Groupon has
selected the library, in my book.

------
christianhager
This is nice! Been using backbone for about a year, and often I wonder if
there are better ways. I'm learning a lot of new solutions by reading this.
Thanks.

~~~
rahuldave
Yes, thanks!, this is fabulous, between the backbone recipes book
(<http://recipeswithbackbone.com/>) and this, and the absolutely fabulous book
by Alex McGaw (author of Spine,
<http://shop.oreilly.com/product/0636920018421.do>), my JS app mojo has been
steadily improving!

------
randall
I think I disagree with the buffer pattern. I'd probably run the function with
an argument of next() so you could keep the function more portable.

~~~
rstacruz
That's how jQuery implements it for jQuery.fn.queue, and I think I'll revise
it that way too.

------
thelonecabbage
not to forget the Memoiz Module pattern from
[http://weblog.bocoup.com/organizing-your-backbone-js-
applica...](http://weblog.bocoup.com/organizing-your-backbone-js-application-
with-modules/)

