Backbone.js Lessons Learned and Improved Sample App

A few weeks ago, I posted a three-part Backbone.js tutorial (part 1, part 2, part 3). Since then, I spent more time building a real-life application with Backbone. I ran into a number of interesting problems, spent time thinking about solutions, and decided to write them down in this post. These are not definitive answers, just my current thoughts… and as always, I value your input.

Based on this new experience, I revisited the Wine Cellar application used in my tutorial. You can find the improved version here (PHP back-end) or here (Java back-end).

Externalizing Templates

In the initial implementation of my wine cellar app, I “inlined” my templates in a succession of <script> tags like the one below inside index.html.

<script type="text/template" id="wine-list-item">
	<li><a href='#wines/<%= id %>'><%= name %></a></li>
</script>

This approach works fine for a simple application with a limited number of templates. In a larger project, it makes templates hard to maintain. It also makes it difficult for multiple developers to work on different templates at the same time. Removing the script body and adding a src attribute to point to an external file didn’t seem to work to load HTML templates.

In this StackOverflow thread, Brian Genisio suggests loading external templates as string variables in a .js file. Using this approach, a template definition looks like this:

app.templates.view = " \
    <h3>something code</h3> \
";

That’s certainly a valid approach, but depending on your circumstances, it may still not be the ideal solution: long string concatenation is painful (especially for larger templates). In addition, if you define HTML in string variables, you will probably not be able to benefit from the HTML capabilities of your editor.

Other people load external templates using Require.js and the text plugin, which is definitely an approach worth considering for larger projects. In my case, I didn’t feel that the size of my project mandated it.

In the end, I decided to write my own simple template loader. It is implemented as follows:

tpl = {

    // Hash of preloaded templates for the app
    templates: {},

    // Recursively pre-load all the templates for the app.
    // This implementation should be changed in a production environment:
    // All the template files should be concatenated in a single file.
    loadTemplates: function(names, callback) {

        var that = this;

        var loadTemplate = function(index) {
            var name = names[index];
            console.log('Loading template: ' + name);
            $.get('tpl/' + name + '.html', function(data) {
                that.templates[name] = data;
                index++;
                if (index < names.length) {
                    loadTemplate(index);
                } else {
                    callback();
                }
            });
        }

        loadTemplate(0);
    },

    // Get template by name from hash of preloaded templates
    get: function(name) {
        return this.templates[name];
    }

};

I use it to preload all my templates before bootstrapping Backbone:

tpl.loadTemplates(['header', 'wine-details', 'wine-list-item'], function() {
    app = new AppRouter();
    Backbone.history.start();
});

Loading templates separately is great during development: you can modify and test individual templates without requiring a “build” or the concatenation of multiple template files. In production however, loading dozens of templates as separate HTTP requests can be a serious bottleneck. So when you are ready to move to production, it’s a good idea to somehow combine all your templates in a single file so that you can load them all with a single HTTP request.


Decouple Views from other DOM elements

In the initial version of my application, I didn’t pay much attention to the way I chose the “el” or “tagName” of my Views. I often assigned the View’s “el” to an existing element of the document.

“Before” code:

window.WineView = Backbone.View.extend({

    el: $('#content'),

    render: function(eventName) {
		$(this.el).html(this.template(this.model.toJSON()));
		return this;
    }

});

… and here is the Router’s code that instantiated and displayed a WineView:

new WineView().render();

After more careful consideration, I realized that this approach wasn’t very good. The View is not fully encapsulated: it “reaches out” to an attribute (element) of the containing document (‘#mainArea’), creating an undesirable dependency. A better approach is to make sure a View doesn’t know about its hosting document. It should not know about (or assume the presence) of other elements in the document. The knowledge of the View should be limited to the elements in its own template. That will make the view reusable in many different contexts. The corollary of this rule is that a View shouldn’t attach itself to a DOM element in its render() method. The render() method should be limited to populating its own “detached” el attribute. The code that invokes the View’s render() method can then decide what to do with the View’s HTML fragment: attach it, append it, etc. The View is therefore more reusable and more versatile.

“After” code:

window.WineView = Backbone.View.extend({

    tagName: "div", // Not required since 'div' is the default if no el or tagName specified

    render: function(eventName) {
		$(this.el).html(this.template(this.model.toJSON()));
		return this;
    }

});

… and here is the Router’s code that instantiates and displays a WineView defined as above:

$('#content').html( new WineView().render().el );

 

Cleaning Up: Avoiding Memory Leaks and Ghost Views

Before getting rid of a view, you need to clean up, which mainly consists of removing the bindings that could prevent the View from being properly destroyed. A View that is not properly destroyed becomes a “Ghost View”: you don’t see it, you think it’s gone, but it still manifests itself in some unpleasant ways: its events are still firing and it still uses memory (memory leaks). Ghost Views often first manifest themselves in the form of events firing multiple times.

In my initial implementation, I provided views with a close() method that took care of cleaning up. There was nothing wrong with that approach except that you had to remember to call the close() method!

Derick Bailey has a great post on this topic and provides a more generalized approach: It consists of adding a generic close() method to the Backbone View prototype. I borrowed Derick’s approach and implemented my generic close() method as follows:

Backbone.View.prototype.close = function () {
    if (this.beforeClose) {
        this.beforeClose();
    }
    this.remove();
    this.unbind();
};

The call to beforeClose() (if it exists in the view) is a hook to add some view-specific cleanup code if required.

In your Router, you then create new Views by invoking a custom showView() method that invokes close() on the currentView before replacing it with the new View.

showView: function(selector, view) {
    if (this.currentView)
        this.currentView.close();
    $(selector).html(view.render().el);
    this.currentView = view;
    return view;
}

Note that this is only part of the solution. For example, if you have composite views (views containing other views), you still have to make sure you close the “child” views when the parent view is closed. A good approach here is for the parent view to keep track of its child views so that it can call their respective close() methods when its own close() method is invoked. The beforeClose() method (explained above) of the parent View is a good place to close the child Views.

Route pre-processing (aka Filters)

Backbone’s Router is great at routing requests to the important/stateful/bookmarkable locations in your application.

When defining the routes in my application, I sometimes find myself in a situation where a pre-condition has to be met before a route can be taken.

For example:

  • Some routes may require the user to be authenticated.
  • Some routes may require some data to be loaded.

It’s easy to verify the pre-condition in the method that implements a specific route. That’s what I did in the initial version of my application. But in a larger application, this approach will quickly start cluttering your route methods.

My instinct was to look for a “Filter” feature in the Backbone Router API, but it doesn’t currently exist out-of-the-box, and in this thread, Jeremy makes the case that the same result can be achieved using underscore’s _.wrap() method.

_.wrap() didn’t work for me because my pre-condition involved asynchronous processing and I can only pass control back to the routing method after the successful completion of my async code.

In the end, I implemented a simple/low-tech before() method that is somewhat similar to wrap() but supports async chaining.

var AppRouter = Backbone.Router.extend({

	routes: {
		"wines/:id"	: "wineDetails"
	},

	wineDetails: function(id) {
        this.before(function() {
			var wine = app.wineList.get(id);
		    app.showView( '#content', new WineView({model: wine}) );
        });
  	},


    showView: function(selector, view) {
        if (this.currentView)
            this.currentView.close();
        $(selector).html(view.render().el);
        this.currentView = view;
        return view;
    },

    before: function(callback) {
        if (this.wineList) {
            if (callback) callback();
        } else {
            this.wineList = new WineCollection();
       		this.wineList.fetch({success: function() {
               $('#sidebar').html( new WineListView({model: app.wineList}).render().el );
               if (callback) callback();
            }});
        }
    }

});

This solution is not as “decoupled” as a traditional filter implementation would be, but it allowed me to unclutter my code in a way that was suitable for my requirements. Jake Dempsey
has built a more traditional filter implementation here that you may want to take a look at.

Download

The source code for this application is hosted on GitHub. The application uses RESTful services to access the data.

For a version of this application using a PHP back-end, use this project (use the ‘final’ folder for the version of the application discussed in this article.

For a version of this application using a Java back-end (using JAX-RS), use this project.

68 Responses to Backbone.js Lessons Learned and Improved Sample App

  1. Renan Santos January 31, 2012 at 2:46 pm #

    Backbone has just been released to version 0.9.
    “Added an undelegateEvents to views, allowing you to manually remove all configured event delegations.”

    • Alpar April 22, 2013 at 2:15 pm #

      You commented in the first snippet that: “This implementation should be changed in a production environment, all the template files should be concatenated in a single file.”

      Why shouldn’t one use this approach in production?

  2. Tim Branyen January 31, 2012 at 9:49 pm #

    A few thoughts:

    Since your template function accepts an array of template files, you should leverage the inherent deferred nature of jQuery.ajax. Basically you would push all the $.get requests into an array and then do $.when.apply(null, requestsArray);

    This change would be significantly more performant and result in cleaner code.

    Your rendering using html should have a detach on the element before placing into the DOM. Otherwise if you later on decide to cache your View, resulting in the reuse of a View.el all delegateEvents will be lost. jQuery’s html function does not have a supported signature for DOM Nodes and under the hood it will call empty() on the element resulting in all events to be purged. This is not an immediate issue as your code constructs a new element every time, but in the future presumably Views could be cached.

    I’ve been thinking about Router filters as well and I have an implementation that kept consistent naming as your approach. You may consider a before handler with an array of functions and then a callback once they are all done.

  3. Christophe February 2, 2012 at 8:47 pm #

    Thanks Tim. Will update the sample. Would love to see what you came up with re: filters.

  4. Jason February 7, 2012 at 1:13 am #

    Hey Christophe,

    Is there any reason why you chose to use: “$(‘#content’).html( new WineView().render().el );” instead of “new WineView( { el: ‘#content’ } ).render();”

    • Daniel June 7, 2012 at 1:53 pm #

      That seems to be the point of that portion of this post. Christophe is making the argument that the WineView view should only be responsible for rendering its “inner self,” without including any reference to DOM elements that might already be on the page. This makes the render function more “functional” in the Functional Programming sense of the word, which in this case makes the view more reusable and even composable with the output of other views’ render() methods.

      He then uses the $(‘#content’).html( new WineView().render().el ) as an example of how one would then take that output and insert it into a specific page. So while your two options may be equivalent for the output of a given page, the way that Christophe describes has several advantages for the organization of an app as a whole.

  5. Luc Stakenborg February 7, 2012 at 12:33 pm #

    Hi,

    I like the template loader!

    I would like to point out a minor issue: when you define a View with tagName property, Backbone will create an element for you during the initialization of the code. So when you define the WineListItemView with tagName “li”, you shouldn’t include “” and “” in the view templates too. This will cause nested li elements.

  6. Luc Stakenborg February 7, 2012 at 12:39 pm #

    Oops, the html tags got filtered out in my last comment. I meant to say .. you shouldn’t include the ‘li’ element in the view templates too.

    • Christophe February 9, 2012 at 9:59 pm #

      Hi Luc,
      Good catch. I fixed it in the GitHub repository.
      Thanks,
      Christophe

  7. Xmoki February 14, 2012 at 1:15 am #

    Hi,
    Currently i’m interested on learning backbone and slim framework, i found great tutorials here. I’m a noob at this type of libs specially backbone, so i’m playing with this tutorials.

    So i went into a problem: i tried to use backbone.history pushState, resulted on url change but didnt fire route function, i figured that i would have to use {trigger:true, replace: true} arguments on backbone.history but it doesnt work. I dont know if i’m understanding correctly how to work with pushState, any help appreciated.

  8. Marta February 14, 2012 at 8:53 am #

    HI, it is a very nice tutorial and I have learned a lot but there is something wrong when I’m trying to save a new wine:-( It doesn’t work. Do You know why?

  9. Matthew Nelson February 14, 2012 at 9:37 pm #

    Another great way to decouple views from the DOM is to give the constructor an element to use.

    new WineView({ el: ‘#content’ }).render();

    • dja May 9, 2012 at 5:31 pm #

      good point. why would I want to litter my markup with a bunch of generic unsemantic …?

      • dja May 9, 2012 at 5:32 pm #

        sorry, it commented out the div markup*

  10. Ian February 20, 2012 at 9:11 am #

    This really is a fantastic set of tutorials on using Backbone.js, PHP, and MySQL together in a way that would be used in a real-world application. In all other Backbone tutorials it stops short at combining PHP and how to save and retrieve data .I particularly like the combination with PHP Slim Framework – it’s fantastic! It’s very interesting to see how you changed your thinking on views and JS templates, all very useful to know.

    Any chance you could include some tutorials on working with Mustache templates or Handlebars.js (a superset of Mustache with many shortcomings elegantly addressed)? Have you considered saving and storing your template files as separate files and calling them in like this: http://www.jblotus.com/2011/05/24/keeping-your-handlebars-js-templates-organized/ ?

    Thanks!

  11. Lendar February 25, 2012 at 6:43 pm #

    Excuse me, but what about responsiveness?
    You might have 20 templates, that’s 20 HTTP queries every page load. It is a huge cost for provided benefit.

    There are basically 3 solutions:
    – SPDY instead of HTTP
    – HTML5 local storage
    – compiler which pastes templates into a single file (+compressing them)

    Each of them is pretty easy to implement. But we don’t have a “standard” way, don’t we? Yet.

    • Shaheen Ghiassy February 24, 2013 at 11:22 pm #

      I imagine coenraets is of the caliber of developer that would have a build process (ex: Rake) for his application; thereby having only 1 templates file in production.

      As a matter of the development environment, its much better to have templates in separate files for debugging purposes.

  12. line focus March 1, 2012 at 5:22 am #

    How to build group swf file single project thats run ipad any one help me

  13. Dreyfus March 23, 2012 at 6:49 am #

    Great POST! i learned alot from it. I took your code for the loading of templates but my concern is when you said something like this ” it’s a good idea to somehow combine all your templates in a single file so that you can load them all with a single HTTP request.” What do you mean by this? and how can it be done? THANK YOU. KEEP POSTING MORE GREAT INFORMATIONS.

  14. Justin March 26, 2012 at 3:08 am #

    Great work!
    Thanks!

  15. Jeremy April 6, 2012 at 4:43 am #

    Fantastic post, great stuff here!

    I couldn’t help but notice that a lot of this is abstraction of some boiler-plate Backbone code, as well as common design/coding patterns. I recently came across a great project called Marionette — I’m not sure if you have heard of it, but it’s basically an extension (plus some additions) to Backbone, but it doesn’t clobber it in any way; it’s beautifully written and well documented. I recommend you take a look, https://github.com/derickbailey/backbone.marionette

    Keep it up!

  16. bezieur April 14, 2012 at 7:02 pm #

    I’ve got the similar issues with el element. If I use “generic” approach and I have to add some jquery ui elements.. eg. date time picker, I’ve got to have fixed DOM elements…

  17. Ricardo April 25, 2012 at 7:40 pm #

    Great stuff here, thank you for sharing.

    One thought about the template loader: as great as the idea of preloading a single file with all templates concatened (and therefore preventing the ugly pollution of the HTML markup with script templates), passing the actual start of the application as a callback means that nothing will happen on the page before the templates are loaded.

    If there are 200kb of templates and the user is on a slow connection, he will see nothing but a blank page before the entire markup is loaded. So why not find a reasonable approach to load only the appropriate template on the fly? Currently I’m loading the template, similarly to your script, but it also accepts an element (tipically the this.el element) to which the template will be loaded into. Not quite there yet, but I think this just might be the best and most responsive approach.

    Any thoughts? Cheers!

  18. Chiite May 11, 2012 at 9:17 am #

    Hi,

    Very nice stuff, Thanks.

  19. dja May 11, 2012 at 2:21 pm #

    what i don’t understand about the ‘ghost’ views is why you don’t just use singleton views in order to make sure there’s only one instance of the view?

    http://japhr.blogspot.com/2011/09/singleton-views.html

  20. Joe Zim May 27, 2012 at 3:11 pm #

    Hello. I was wondering if I could use this app as an example on my website. I wish to do a video tutorial series walking step-by-step through creating a Backbone app and I’m having a hard time coming up with a great app to do. I would surely give you credit for the app and link back to either this site or the Adobe articles, (whichever you’d like).

    Please reply to me via email.

  21. Chris Nunciato June 21, 2012 at 8:15 pm #

    Seriously appreciate your sharing all this stuff, Christopher. I’ve read a couple of books covering Backbone already as I push through a first app of my own, but I continually return to your blog (and repos) for clarity and insight. Thank you, sir!

  22. Siby Easow July 1, 2012 at 12:41 am #

    The callback back() method came in handy for me to validate user authentication. Thank you, sir!

  23. Gaurav Ramesh August 10, 2012 at 8:52 am #

    Hi. Really good thing you did with the usage of “el” property. How do I bind events to the elements that my view renders , because as I understand , “events” property in views only works on elements that’s contained in your “el” element. But as we are dynamically adding the “el” itself, how do we go about registering events for those ? Sorry if the doubt is basic. I’m just staring out with Backbone. Thanks for help.

    • GarciaWebDev August 14, 2012 at 3:40 pm #

      I believe you should bind the event on the view itself.

    • daden August 22, 2012 at 1:12 pm #

      I’m running into the same problem — within the view I’m rendering to this.el which is a view-internal element. Outside the view, after the view has been instantiated, I’m populating a DOM element with the contents of the view’s “el.” The problem is that the view events in the form { “click .someselector” : “func” } appears to be binding to the this.el so the events never fire when I click on the DOM element.

      I’m playing around with Backbone.View.delegateEvent() at least to verify — and when I replace the delegate() call in delegateEvent() to something like “$(document).delegate( ‘#domEl selector’, eventName, method)” the events fire.

      Any suggestions for how to get the ‘events’ property to work automatically to bind to the elements in the DOM that are rendered from the internal this.el?

      • daden August 23, 2012 at 10:26 pm #

        One solution is to use replaceWith() to move the element from the view to the DOM as that keeps the events:

        $(“#targetElement”).replaceWith( myView.render().el );

        this apparently moves the contents of el to the DOM so there may be issues if you need to access it within the view later, but for my situation it works fine.

  24. Jiri Balcar August 14, 2012 at 10:04 am #

    Hi, thank you for this example. It is really great and helped me to understand so many things you can do vith backbone. But I have troubles with user authentication to this app. Can you try to add this functionality? Or someone else have a working example? Thank you again and looking forward to next posts.

  25. bala September 11, 2012 at 12:46 pm #

    There is a maven plugin i have authored to support large sets of templates and combine them into a javascript file. hopefully it will help solve the problem of organizing templates. you can find it here “https://github.com/balachandra/add-to-javascript”

  26. Matt Liberty November 10, 2012 at 1:10 pm #

    This is a great series but the code samples are this page are totally garbled. I see “<script …”. I see the same issue on the original articles too.

  27. Hans January 10, 2013 at 3:57 pm #

    It is a great tutorial, but please do us security people a favour and change the code for wine-list-item.html and wine-details.html so that the application has no XSS (cross site scripting) vulnerabilities any more. It is easy. Change

    to
    to

    and so on. Or even easier to

    to
    to

    Wouldn’t be so good, if to many developers copy this code without knowing what they do.

    • Hans January 10, 2013 at 4:04 pm #

      Oh, the blog isn’t escaping HTML characters correctly!

      You should change

      <%= name > to <%= _.escape(name) >

      or even better to

      <%- name >

  28. Dan O'Keefe February 6, 2013 at 7:31 pm #

    Hi Christophe,

    Fellow Adobe developer here (ColdFusion). I inherited a CF app that makes heavy use of Backbone. We are loading our templates using the template loader and your “before code”. In addition, the previous developer was loading them into local storage, and now I am trying to figure out how to push updates to the user and avoid them having to purge their cache. Any thoughts? If not, no worries, I know its outside the scope of your post.
    Thanks

  29. Rob D February 8, 2013 at 11:55 am #

    A very interesting article. However, with regards to decoupling, aren’t you simply swapping the coupling between a view and the dom to one between the router and the dom? Whilst I recognise that if you use the view in other situations your approach would be better, surely a View, almost by definition, is contextual, whereas a router is channeling requests and linking models and views and it shouldn’t be delving into the dom.

  30. What is the best way to i18n that kind of software? February 11, 2013 at 9:12 pm #

    Hi and thanks a lot of your tutorials! What is the best way nowadays i18n client-server softwares in your opinion? I used properties, but how that solution can be integrated to client-server app?

    Sami

  31. Ore4444 February 20, 2013 at 11:50 am #

    You can update the “Cleaning Up: Avoiding Memory Leaks and Ghost Views” section as your technique is unneeded since Backbone 0.9.9 because it calls view.stopListening() during view.remove().

  32. Vincent March 17, 2013 at 6:26 pm #

    Hey Chris,

    I have an issue with the tpl.loadTemplates function. It seems for some reason it might break the routing of backbone. Could you please take a look at:
    stackoverflow.com/questions/15455299/backbone-router-issue-will-not-load-specific-action-when-accessed-through-the

    And let me know if i am doing something wrong or something with the function as other people mentioned.

    Thanks.

  33. Patricio Sánchez March 28, 2013 at 1:19 am #

    Chris. I like your template engine. It’s very straightforward and defines a very nice structure to create Backbone.js apps. I’m using in my software projects at the company I work.

    It would be awesome to have a scaffolding app to create all that folders with wizards to create Views, Models and manage the routing. Do you know an IDE that can help with that? May be it could be a big challenge but a very interesting project.

    I’ve followed you at twitter to know more news about your ideas.

    Thanks,
    Patricio

  34. Alpar April 22, 2013 at 2:18 pm #

    You commented in the first snippet that: “This implementation should be changed in a production environment, all the template files should be concatenated in a single file.”

    Why shouldn’t one use this approach in production?

    • Christophe Coenraets April 23, 2013 at 2:06 pm #

      @Alpar. Usually people would want to minimize the number of HTTP requests made to the server. Especially if they are all made at the same time (startup time). So concatenating the template files will load all your templates with a single HTTP request. Alternatively you could also load the templates on demand.

  35. David Gilbertson July 23, 2013 at 7:51 pm #

    I’m new to all this, so forgive a potentially bad idea, but on the template front, if you’re using php in the backend, could you have your multiple templates in php files and use includes to bring them all in to the main page?
    Everything is then separate as far as editing the files are concerned, but combined server side before sending to the client.

  36. akoskm September 17, 2013 at 2:05 pm #

    Great work! Came to similar conclusions after a few months of using Backbone.

  37. Jacob Duncan October 8, 2013 at 12:29 pm #

    Hey Christopher,

    I firstly want to say thanks so much for the cellar tutorial, it helped me to start with Backbone so much!

    I was just wondering if you knew much about JAX or if you would point me in the right direction?

    I have your project modified for mine and it runs fine, but I would like to know how I can get it to run on my tomcat instance that automatically runs all my projects through “webapps” folder? I can only get it to run when I choose “Run on server…” in Eclipse, not automatically through my tomcat server startup?

    Thanks again mate!

  38. Narayan October 25, 2013 at 5:24 am #

    Im new to backbone framework, im trying to learn your example by implementing the same using require.js

    How could I implement the following code using require.js

    Backbone.View.prototype.close = function () {
    if (this.beforeClose) {
    this.beforeClose();
    }
    this.remove();
    this.unbind();
    };

  39. demirdöküm November 6, 2013 at 6:31 am #

    Note that this is NOT “wrong.” Backbone does not establish how anyone uses the MVC pattern. But to me, it sort of broke the concept of a ‘Collection’ of ‘Models’. Creating such a variable (‘reports’) within the ‘Employee’ model may well be the best implementation and certainly shows the power of Backbone to do whatever you want. I just thought it needed some clarification

  40. demirdöküm servis November 6, 2013 at 6:32 am #

    Rex Ryan Talks Trash About authentic nfl jerseys authentic nfl jerseys Vs.
    Multiple sources, including ESPN, are reporting that the Saints are
    going into this season with the team, according to NBC Connecticut.
    Marshawn Lynch did put together another good game, rushing for 474 yards and 5
    touchdowns. Could the Green Bay Packers and first appeared as if they are
    found innocent in the long term.

  41. demirdöküm kombi servisi November 6, 2013 at 6:32 am #

    Oh my goodness! a fantastic write-up dude. Thank you Nonetheless I’ll be experiencing trouble with ur rss . Do not know why Struggling to sign as much as it. Probably there’s any particular person getting identical rss difficulty? Any individual who knows kindly respond. Thnkx

  42. demirdöküm soba servisi November 6, 2013 at 6:33 am #

    love your blog.. very nice colors & theme. Did you design this website yourself or did you hire someone to do it for you? Plz answer back as I’m looking to design my own blog and would like to find out where u got this from. thanks a lot

  43. majji November 7, 2013 at 4:40 am #

    nice work .we are new to backbone.js but we were learning so many things from your sample apps . greate work and we are all waiting for your new concepts and new apps.
    thanks…….

  44. Nagesh February 7, 2014 at 7:14 am #

    Great example for beginners like me…
    I was more interested in the views clean up functionality which you implemented with close.
    But the dome is not cleared and still being held in the memory.
    I checked using profile of Chrome, and found that app which is the router is holding the el, can you suggest how to get cleaned up. I have given the snapshot below from el to app…

    el in child @268343
    9
    160 % 3 7160 %
    ctx in @264793
    8
    240 % 3 7400 %
    [1] in Array @264409
    7
    160 % 3 8560 %
    change in @264401
    6
    120 % 6 4680 %
    _events in child @263865
    5
    160 % 6 6080 %
    [2] in @264161
    4
    120 % 1160 %
    _byId in child @263501
    3
    160 % 10 4720 %
    wineList in child @247917
    2
    120 % 4640 %
    app in Window / localhost:8380/testbb/wine.html#wines/3 @229971
    1
    400 % 5 6680 %
    router in system / Context @283031

  45. Kevin April 8, 2014 at 11:02 am #

    Does anyone have an authentication example used with this tutorial they would share ?

    Thanks
    Kevin

Trackbacks/Pingbacks

  1. 2012년 2월 3일 it 기술 동향 « jangnan - February 3, 2012

    [...] 예제를 만들어보며 배우는 backbone.js http://coenraets.org/blog/2012/01/backbone-js-lessons-learned-and-improved-sample-app [...]

  2. Backbone.js Wine Cellar Tutorial — Part 3: Deep Linking and Application States - February 16, 2012

    [...] UPDATE: I posted a “Postface” to this series with some lessons learned and an improved version of the app. Make sure you read it here. [...]

  3. Design2U » [Javascript] Backbone.js (一) Hello backbone - July 23, 2012

    [...] Backbone.js Lessons Learned and Improved Sample App [...]

  4. Confluence: Windmill - September 10, 2012

  5. Avoiding zoombie screens and memory leaks in backbone architecture - Adriel Blog | Adriel Blog - September 14, 2012

    [...] http://coenraets.org/blog/2012/01/backbone-js-lessons-learned-and-improved-sample-app/ Be Sociable, Share! TweetNo TweetBacks yet. (Be the first to Tweet this post) Categories: html5 Tags: Comments (0) Trackbacks (0) Leave a comment Trackback [...]

  6. Sample App with Backbone.js and Twitter Bootstrap | Christophe Coenraets - November 16, 2012

    [...] you are new to Backbone.js, you may want to start with the tutorial (part 1, part 2, part 3, and postface) I blogged recently. “Backbone Directory” includes some interesting elements not [...]

  7. Sample Mobile App with Backbone.js and PhoneGap | Christophe Coenraets - November 17, 2012

    [...] recently blogged a tutorial (part 1, part 2, part 3, and postface) that takes you through the process of building a CRUD application using HTML and the Backbone.js [...]

  8. Externalizing Backbone.js templates into separate files | cjlarose - December 12, 2012

    [...] Some recommend putting those templates into separate .html files and getting them all via AJAX.  That’s really nice for workflow, but it’s really expensive if you have a lot of templates.  We can do better, still. Rico Sta Cruz recommends using JST Templates.  This means that you define your templates in separate files on the server, and your server-side code takes care of putting it all together into a single JavaScript file.  This is ideal, in my opinion, for most projects.  And if you’re using Rails, EJS will do the heavy lifting for you. [...]

  9. Requirejs to load templates without model definition | Code and Programming - December 31, 2012

    [...] In addtion to the answer, a lighter solution is here http://coenraets.org/blog/2012/01/backbone-js-lessons-learned-and-improved-sample-app/ where you load all the templates initially which may be better than loading as needed. This entry [...]

  10. Learn Backbone.js Completely | JavaScript is Sexy - January 14, 2013

    [...] these two tutorials: — 
Backbone.js Wine Cellar Tutorial — Part 2: CRUD 

— 
Backbone.js Lessons Learned and Improved Sample App
 (This is a MUST [...]

  11. Developing Java web applications with Backbone.js - April 26, 2013

    [...] 1> Backbone.js Lessons Learned and Improved Sample App [...]

  12. BackboneJS: Why should we use a MasterView? | A UX Developer Guide - June 6, 2013

    [...] keep the DOM away from script tags. For more information on external template loading please visit Christophe Coenraets blog, where he has specified some of the best practices while creating a Backbone [...]

Leave a Reply