Intro To Backbone.js: How A Winforms Developer is At Home In Javascript

Today, I was introduced to Backbone.js and I almost immediately fell in love with it. It’s powerful. It’s elegant. But most of all, it’s a set of design and interaction patterns that I have a lot of experience using.

NewImage

 

MV* In Winforms

Prior to going indy and into rails work full time, I spent 4 years working with Winforms applications in .net – both desktop and mobile with Windows Mobile 6. In those 4 years (and various other projects in the past) I learned a lot about building winforms applications with various architectural patterns. In the end, I settled into the use of the various MV* patterns as I found them to be the most useful, long-term.

I’ve implemented apps with MVP and MVVM, including variations of these like Passive-View and Active-Presenter, etc. All of these MV* patterns are just various degrees of implementation differences but they all have the same goal: separating the concerns of view layout and display from the view’s logic and processing and the model(s) that provide the business value.

I’ve become very comfortable with these patterns and I know how to make them work well in a very organized manner, keeping the code clean and easy to understand.

 

Hack-And-Slash Javascript

On the other side of the dev world, though, I’ve always struggled with writing good javascript. I’ve been using javascript in various forms since Netscape 2.0 introduced it to the world back in the mid 90′s… but I’ve never really felt comfortable or productive with it.

Even with the wonderful things that jquery has done for javascript in the last few years, when I get more than just a few dozen lines of javascript into a page, my code quickly becomes a mess. I almost invariably resort to hacking and mashing things together in order to get things to work. Sure, I use callbacks and cool jquery code… but it’s an unorganized, procedural mess with callbacks mixed in.

Even after spending the weekend learning more about object-oriented javascript, the result of my efforts were little more than procedural-callback-laden hacks in the guise of an object, hidden behind a namespace. But, I was learning and I continued on. The good news about my effort to learn more OOJS this weekend was that it made what I was about to see, much easier to understand.

 

Enter Backbone.js: MV* In Javascript

I’m not going to get into a discussion about whether Backbone is MVC, MVP, MVVM, MV-YourMinisculeDifferenceNamedHere or whatever… backbone is an MV* implementation in javascript, plain and simple.

After spending the afternoon working with Joey and using backbone, I finally feel like I’m writing good, organized, easy to understand javascript. So far, I’ve used Models, Collections and Views with backbone. It also supports controllers, but I haven’t yet played with them. I’m sure there’s some great use for them but I’ll get to them later.

Now, I’m not going to try and lull you into a sense of security and say that if you’ve ever written a line of MV* patterns in .NET Winforms apps, you’ll get off the ground running with Backbone in no time. There is still a significant learning curve – or, at least there was for me – because you have to know the core of object oriented javascript to really understand what Backbone is doing. However, if you are familiar with object oriented javascript and MV* implementations in Winforms applications, you should have no trouble seeing the same patterns of usage and implementation emerging in your Backbone code. For now, I’ll assume you know enough about javascript and jump right into some very simple Backbone examples.

 

Models: More Than JSON

When working with JQuery, I tend to work directly with JSON documents as DTOs. These documents are very useful for a number of reasons. They can transport data around, they have methods that manipulate the data, and JQuery can use them to populate templates with the JQuery template plugin. However, there are some things that are distinctly lacking in JSON documents. For example, there’s no event system to know when your models are changing. While it’s not terribly difficult to build some functionality like this, it can get tedious to repeat the code through your documents and troublesome to add it to documents that come out of back-end web servers such as Rails or ASP.NET MVC.

Backbone models to the rescue!

Here’s an example of how you can build a model in Backbone and listen to an event to know when a field has been changed:

var SomeModel = Backbone.Model.extend({});

someModel = new SomeModel();

someModel.bind("change", function(model, collection){
  alert("You set some_attribute to " + model.get('some_attribute'));
});

someModel.set({some_attribute: "some value"});

 

The result of running this example is that you’ll have an alert box:

Screen shot 2011 06 14 at 10 36 07 PM

You’ll notice in the code that there’s a few obvious JSON documents (easy to see w/ the { } brackets) but that the model we’ve defined doesn’t use the standard JSON object notation to get and set attributes. Rather, you have to call the .get and .set methods to get and set attributes. I’m not 100% sure of why this is, but I’m assuming it is to facilitate all of the other functionality (like events) that the backbone models support. This takes a bit of getting used to, but I think I can see why it’s necessary.

There’s an easy way to get a JSON document out of this model, though, in case you want to get back to something a little more simple:

var someJSON = someModel.ToJSON();

 

There are a lot of things you can do with models, in Backbone. This little example doesn’t really show much, though, because a model in isolation is less useful than one used in the page somewhere.

 

Views: No, Not The One That You Rendered From Your MVC Back-end

Remember, Backbone is a complete MV* setup in your javascript, and it supports the idea of views. While a view in Rails or ASP.NET MVC represents pretty much the entire chunk of HTML that will be sent down to the browser, a view in Backbone seems to represent a smaller piece. From the examples I’ve seen and the code that Joey and I wrote earlier today, a view tends to be a logical chunk of the larger page. For example, you may have a small form on a login page where you enter your username and password. This form may be represented as a view, while the dozens of other logical groupings of visual elements may or may not be represented as other views.

Here’s the super-simple html that you may see for a login form:

<form action="/login" id="login-form">
  Username: <input type="text" id="username"><br>
  Password: <input type="password" id="password"><br>
  <button id="login">Login</button>
</form>

 

This produces an amazing UI, of course:

Screen shot 2011 06 14 at 10 59 58 PM

You could turn this simple form into a Backbone view and have that view process the login request with an AJAX/JSON request back to the server. To keep things simple, though, I’ll just show an alert with the data that you populate into the form fields:

var Credentials = Backbone.Model.extend({});

var LoginView = Backbone.View.extend({
  el: $("#login-form"),

  events: {
    "click #login": "login"
  },

  initialize: function(){
    var self = this;

    this.username = $("#username");
    this.password = $("#password");

    this.username.change(function(e){
      self.model.set({username: $(e.currentTarget).val()});
    });

    this.password.change(function(e){
      self.model.set({password: $(e.currentTarget).val()});
    });
  },

  login: function(){
    var user= this.model.get('username');
    var pword = this.model.get('password');
    alert("You logged in as " + user + " and a password of " + pword);
    return false;
  }
});

window.LoginView = new LoginView({model: new Credentials()});

 

Run this, enter a username of “qwer” and a password of “asdf”, then click the Login button and you’ll see this:

Screen shot 2011 06 14 at 11 36 12 PM

I’am mixing both Backbone and JQuery into this example. I find JQuery a little easier to deal with in some cases, and I also wanted to show that it’s entirely possible to mix the two together. Many of the examples that you’ll find online also mix the two together ’cause frankly, JQuery is awesome. It solves a different set of problems than Backbone does, as well, so why not mix them together?

There are a number of things to pay attention to, other than mixing JQuery and Backbone, though.

I’m creating a Credentials model that we are using to store the username and password that are entered. The View is then defined as a JSON object with a few key bits of data and a few functions of our own.

The first bit of data is the “el” attribute. This is an attribute that Backbone recognizes as the element that the view encompasses. There are other ways of saying this and getting the view to know which part of the HTML document it represents, but for this example, “el” is all we need. In this case, I’m assigning the entire form to the view’s element.

The next bit of data is a list of events that the Backbone view will listen to. In this example, I only chose to listen to the click event of the #login button with Backbone. I could have listened to the change event for the username and password entry as well, but I wanted to show how you can mix JQuery in for those events. The click event for the #login button fires the login function as the event handler.

The initialize function is the constructor of the the view. When initializing the view in the very last line, I am passing a {mode: new Credentials()} JSON document in. ‘model’ is a recognized part of Backbone. When I call “new LoginView({model: new Credentials()});”, I am assigning the view.Model to the new Credentials object. This gives me access to “this.model” all throughout the view’s code – like in line 21.

I’m using JQuery to find the username and password fields, and binding to the change events for them. Once the change events fire, I’m populating the value from the input boxes into “self.model”. Notice the discrepancy between the word “this” and the word “self”? This is a workaround for the scoping of “this” in javascript. When switching scopes between a Backbone object and a JQuery callback method, “this” changes to the JQuery object that fired the event. The work around is to assign a local variable to “this” prior to entering the JQuery code. Line 11 does this, setting “self = this”. Then in the JQuery callbacks, I can still reference the Backbone view as “self” and get to the view’s model to set the attributes as needed.

Once all of the work is done to bind the input boxes to the model, the login function uses it to display the alert box with the correct information.

Lastly, setting “window.LoginView” on the last line is a way to keep the view object alive. For a brief and insightful discussion on what “window” does, see this question that I asked on StackOverflow earlier today.

 

The Complete Working Example

If you’re interesting in seeing the entire example that I showed here, head over to the gist and look at the last file. It’s everything – the html and javascript – all in one.  You’ll just need to download the right versions of Backbone, JQuery, JSon2, and Underscore.

 

Finding My Comfort Zone With Javascript

Although the syntax and implementation detail are significantly different than any winforms project I’ve ever written with an MV* pattern, there is a strong familiarity with the patterns that determine how I’m implementing this example. I’m used to seeing an event driven viewmodel (the “View”) that sets up databinding and other functionality. I’m used to having a clean separation between the view, a viewmodel, and a model representing the data. The patterns of interaction between these various pieces are comfortable to me and I was able to leverage my experience with these patterns to help Joey and I move our Rails project forward today, creating a very complex set of interactions with a very well structured javascript file.

In the end, I realize that I have a lot more to learn about Backbone. I’ve only touched the surface with these examples, but I’ve already done much more in my actual app. I’ve also realized just how terrible my old jquery-heavy javascript code really is. I look back at the javascript file that I put together over the weekend, while building the interactions I needed for a medication list, and I want to tear my hair out. But when I look at what I’ve built with this example and what I helped Joey build in our app, I see hope and I see a way out of the mess that I’ve previously caused in my apps.

I finally feel at home, working with Javascript. And that’s a good feeling.


Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs SignalLeaf.com - the amazingly awesome podcast audio hosting service that everyone should be using, and WatchMeCode.net where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in Backbone, Design Patterns, Javascript, JQuery, Model-View-Controller, Model-View-Presenter. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://murrayon.net/ Mike Murray

    Backbone is pretty awesome indeed. We actually were running Knockout and Backbone together for a little while, and then realized there was quite a bit of overlap in the goals and objectives of each project. We ended up preferring Knockout’s syntax and features, but if you’re gonna do any serious JS development, you’ve got to use at least one of these two great libraries!

    http://knockoutjs.com/

  • Mihai Lazar

    I haven’t looked at Backbone yet. I’m considering using KnockoutJS and jQuery for our new project.

    Spine at http://maccman.github.com/spine/. Looked pretty nice. I actually tried porting spines todo list example to knockout just to see what difference it would make.

    So if you like MVVM, knockout might be better suited. But if you want MVC, Spine might peek your interest.

  • http://twitter.com/EisenbergEffect Rob Eisenberg

    Great example. I’ve been watching backbone for some time now. My biggest issues with it and many of the javascript MVC frameworks is that they make you write a ton of code for even the simplest things. It’s well factored code, but it’s a lot of imperative code and could be cut in half by embracing a more declarative style. That’s the advantage of using Knockout, for example. What you are showing would be about half the code in Knockout, maybe even less. However, it’s not clear to me that Knockout has a story for how it can scale to very large projects, where as it seams that Backbone may. I’ve been doing a lot of research and work in this area, developing my own framework based on Silverlight and Caliburn.Micro, but completely in Html/Js. I’ll try to have a sample like this when I show it off so that we can have some compare/contrast. Derick, if you are interested, drop me an email and I’ll put you on my “special” list :)

  • http://twitter.com/rstackhouse Robert Stackhouse

    Aren’t Backbone and it’s ilk just another go at beating something new into what we are used to (for those of us that started off in compiled languages—i.e. models in which events can be defined upon ad nasuem).

    Wasn’t the reason that JQuery won out over Prototype.js its terseness? Aren’t you loosing some of that by using Backbone?

    Isn’t JQuery more of the functional school of thought than the event driven one? Seems like you are mixing paradigms in your code. I wonder how readable the result will be by the developer who comes behind you.

    JQuery thinking has always struck me as, “Do most of the work on the server.” It seems like the developer community is constantly waffling on this issue. When you throw in concerns about cross-browser compatibility (which frameworks like JQuery attempt to handle quite nicely, but will always be leaky abstractions), download size, network speed, and accessibility and pit those against server loads, I guess we will always be on the fence.

    Beyond mixing paradigms (which JavaScript does a “good” job of all on its own), you seem to be mixing opinions (i.e. terse vs. verbose and “close to the metal” vs “metal abstracted away”), which I think has even more potential for causing confusion.

    I guess what I’m trying to say is it feels like you are really fighting the framework by mixing JQuery and Backbone

    One thing I’m tired of in this business is hype. John Resig has always seemed like the world’s biggest fanboi to me. I guess you should drink your own Kool-Aid though if you are a framework author.

    I’ve always had a problem seeing how heavy usage of JQuery could result in anything other than spaghetti, but if it’s ideal is to write as little JavaScript as possible, it’s probably not that big a deal.

    If this solves a problem besides making the new look like the old, please enlighten me.

    Disclaimer: I’ve only used JQuery a bit. Mostly because I couldn’t choke down the John Resig “hawtness”. My perceptions stem from what I can remember in pitches about JQuery, and we all know how reliable human memory is.

    • http://murrayon.net/ Mike Murray

      If you need to write client-side, highly responsive UI’s that use a lot of AJAX for data updates in a web browser, then the goal is no longer to write as little JavaScript as possible. You don’t want to write a ton of JS, but you’re gonna need a good amount to do these type of things. Libraries like these ones make doing that easier and more maintainable. Some of these libraries have solved problems that you don’t have to solve yourself now.

      • http://twitter.com/rstackhouse Robert Stackhouse

        I can see that. What the customer demands right? Wondering who gets sued when the site is deemed not to be 508 compliant: the client or the contractor. Heavy client web apps run that risk.

        I’ve never seen a heavy client app that degraded gracefully. Could just be that I haven’t looked under the covers of enough heavy client sites.
        Guess you could always go the non RIA path. Building a web application twice would seem prohibitively expensive for all but giants like Google or Facebook.

        If anyone has got some solid info on following WAI-ARIA, I’d love to hear it.

        • http://mutedsolutions.com Derick Bailey

          yeah, i wouldn’t do any of this on a site that needs Section508 or other web accessibility requirements met. I’ve done enough of those sites and they are hard enough to do with straight html and always calling back to the server to do any work. :P

          • http://twitter.com/rstackhouse Robert Stackhouse

            All I have to say to that is just keep in mind Target got sued for accessibility for their e-store and lost.

          • http://mutedsolutions.com Derick Bailey

            wasn’t there a major airline sued for accessibility of it’s kiosk checkin systems, as well?

            … also – Brian Hogan makes some really good points in his “Web Design For Developers” book about how accessibility isn’t just for people with various degrees of disabilities anymore. it also cover things like mobile browsers, text browsers, etc. 

            there’s a lot to consider when building an app that uses a framework like this, and audience / device / accessibility is an important factor

    • http://mutedsolutions.com Derick Bailey

      like every tool in our toolbox, you only use it when it’s appropriate. if you’re not experiencing the problems that JQuery or Backbone solve, then don’t use them. 

      maybe you don’t need the highly interactive, rich client side experiences in your systems? or if you do, you’re probably able to build good javascript code without these tools… more power to you! i would love to sit down with your for a day or two and learn about writing good javascript! (seriously… you’re only a few hours away from me… ever make it to austin or near waco where i am?) but as of now, i’m not smart enough to do the rich browser experiences that i need without tools like jquery and backbone.”I guess what I’m trying to say is it feels like you are really fighting the framework by mixing JQuery and Backbone”there’s some insight in this that i need to pay attention to, for sure. i should see what i can / can’t do with backbone, leaving jquery out of the picture. it would give me a much better picture of which problems each framework solves well….you should at least take the time to learn JQuery and/or backbone if you’re going to offer some heated opinions about them. claiming you don’t like something because you can’t stand people that built it / love it, makes you look over-emotional / reactionary, instead of thoughtful and insightful (i know this from experience in doing the same thing too many times. :-/ )

      • http://twitter.com/rstackhouse Robert Stackhouse

        Guilty as charged. Sometimes as a developer I simply feel like a rag doll being pulled a hundred different directions at once, and that’s just by the (insert framework here) zealots, not to mention BAs, coworkers, UX gurus, Accessibility gurus, and the humble end user.

        Thanks for the insight and for gracefully handling this old crank.

      • http://twitter.com/rstackhouse Robert Stackhouse

        I just wish other devs would tell you the value behind doing something (the how and when questions) and let you make a decision for yourself rather than trying to “sell” you. More times than I can remember I’ve had buyer’s remorse.

        Part of that was self inflicted now that I think about it. Some of it was not knowing the technology I was trying to promote the usage of in enough depth to adequately make an informed decision (who’s got that kind of time?). The rest of it was timing and communication (i.e. trying to eradicate my own pain by using x rather than concentrating on how and when using x could solve a business problem).

        • http://mutedsolutions.com Derick Bailey

          +1 to “why” … that’s a very hard thing to describe, though. why is often personal preferences or specific contexts in which a solution works. but it’s an important thing to discuss, as it would help get away from selling and toward education so we can make informed decisions.

          • Anonymous

            Hey guys, I can speak a little to the “Why”…as an enterprise .net dev with 14 others on this team all writing js for a highly interactive app.

            1.) Our application is essentially a specialized report runner, number cruncher and modeler for hospitals throughout the US.  We were tasked with re-writing the criteria for running these reports.  It was a long page full of html form elements, so we decided that dynamically adding criteria on demand would be nice. 

            So we wrote a large js file to describe the html, business rules, client-side validation that each criteria would use.  Then we had a formbuilder which was the driver for the criteria getting painted on the “canvas” (what we called the area where the criteria was placed in the DOM, not to be mistaken with html5 canvas).  We also had a formbuilder.events file which would listen to certain events (deletion, addition, validation etc) of the criterias placed on the page.  And we had other things.

            The result: we started with a team of about 6 and now we’re 14 what we saw was that controlling the js produced by the team was easy at first. 

            But as time moved on people would place templates all over the place, events were scattered, etc. etc.   The app had clean code everywhere except in the js.

            SO THE WHY:

            - So what bbjs gave us was a well documented unified way of doing most things.
            - It gave us great documentation, so getting new team members to understand “how” to do things was much easier.

        • http://twitter.com/jeffdeville Jeff Deville

          Hi Robert, the ‘why’, as I see it is this.  jquery is fine for small tasks in the view.  But then, so was classic asp.  The problem with both is that you wind up mixing view logic with application logic. With jquery, things can get even worse, because you are even storing your data in your views.  Again, no big deal on a small scale.

          It’s only when you start trying to build client-side _apps_ that the power of these frameworks starts to overcome the learning curve.  There are a number of sites where little html is served.  It’s mostly client-side stuff.  When you reach this point, you need a more powerful framework that is testable.  Testing your javascript is really tough when you have jquery everywhere, because you have to build your dom in your tests.  Just one more complication.

      • http://twitter.com/rstackhouse Robert Stackhouse

        Damn, I was hoping you were going to teach me something.

        HTML5TX ring any bells (shameless plug)? I’ll be there with bells on. Come find me then, and maybe we can try to rescue each other’s sanity.

        • http://mutedsolutions.com Derick Bailey

          yeah, i saw an announcement about that event. i’ll have to see whether or not i can make it. would be fun, for sure :)

  • John Teague

    I haven’t used knockout yet, but if you’re building complex pages with lots of components interacting, Backbone definitely helps.  It is designed to work with JQuery and underscore.js (very awesome), so if you’re familiar with these tools backbone is really nice.

    The issue you have with complicated pages is you end up slinging jquery selectors all of over the place if you’re not careful.  That’s what I like about it.

    • http://twitter.com/jeffdeville Jeff Deville

      Backbone does a great job with Models and Controllers, but a poor job w/ views and viewmodels.  Knockout does a great job with views and viewmodels, but doesn’t even try to do anything with models and controllers.  They can work pretty well together.

      • http://mutedsolutions.com Derick Bailey

        FWIW: “controller” is renamed to “router” in an upcoming version of backbone, which is a much better description of what it does and how it behaves. 

        personally, i think backbone does a great job with views and viewmodels when approached as an MVVM perspective. however, i still haven’t looked at Knockout. once i get around to doing that, i might change my opinion :)

  • Anonymous

    by the way, you should jump on the google group for backbone: http://groups.google.com/group/backbonejs/

    • http://mutedsolutions.com Derick Bailey

      joined :)

  • S Satya Suman

    Simple and eloborate

  • Uchiha Itachi