RailsCasts Pro episodes are now free!

Learn more or hide this

Brandon Tilley's Profile

GitHub User: BinaryMuse

Site: http://brandontilley.com/

Comments by Brandon Tilley

Avatar

Sure. There are a few ways to debug your code. With imperative business logic (usually contained inside services), you can still use debugger and step through the code. DOM manipulation and scope binding are done through things called directives (ng-click etc. are all directives), so you can put a debugger in your directives' code and step through it as well.

For view related debugging, you can get access to scopes (which Angular stores on DOM elements) via angular.element([DOM Element]).scope(); there is also a good Chrome extenion called AngularJS Batarang that can help you see the scopes attached to the DOM, and also help you do profiling regarding slow $watches ($watch is the mechanism through which Angular does dirty tracking and automatic view updating).

Avatar

I very much agree with Patrick's comment, but here's another way to think about it:

In a framework like Backbone, you'd have something like the following code (taken from the Backbone website, minus a few lines):

backbone.js
var DocumentView = Backbone.View.extend({

  events: {
    "dblclick"                : "open",
    "click .icon.doc"         : "select",
    "contextmenu .icon.doc"   : "showMenu",
    "click .show_notes"       : "toggleNotes",
    "click .title .lock"      : "editAccessLevel",
    "mouseover .title .date"  : "showTooltip"
  },

  open: function() {
    window.open(this.model.get("viewer_url"));
  },

  select: function() {
    this.model.set({selected: true});
  },

});

In this object which is a view, you are setting up event handlers on various elements. These event handlers call functions on the view object, which delegate to models. You also set up callbacks on various model events (such as change) which in turn call functions on the view object to update the view accordingly.

In Angular, the DOM is your view. When using ng-click, ng-submit, etc., you are setting up event handlers on these elements, which call functions that should delegate to model objects. When using ng-show, ng-repeat, etc. you are setting up callbacks on model events that change the view.

The fact that AngularJS sets up these callbacks behind the scenes for you is irrelevant; the only difference between this and something like Backbone is that Angular lets you write your view declaratively--you describe what your view is--rather than imperatively--describing what your view does.

So, in in the end, <a ng-click="model.set({selected: true})"> really adds no more dependencies than

backbone.js
events: {
  'click a': 'select'
},

select: function() {
  this.model.set({selected: true});
}

...but it sure is a hell of a lot less code. ;)

Avatar

Yeah, this can be a problem, and people have come up with some pretty clever ways to combat the issue. In our case, the content we display lends itself well to rendering some very basic data on the server into noscript tags, and we are going to experiment with that idea first.

Avatar

Thanks, glad to hear you like the site! As far as learning JavaScript and CSS, I'd take a look at Code School--while they have a monthly membership fee, I feel it is well worth the cost. All their courses are interactive (you actually get to write code that they verify works on their servers during practice sessions), and they cover everything from jQuery basics to CSS3 to CoffeeScript to Backbone and beyond. They even have some really great Rails courses for programmers of all expertise levels.

Avatar

Thanks for the feedback! The mobile web experience is in flux at the moment, but we do have native iOS apps that are pretty awesome! ;) [Edit: I just notice you already said you knew this. My apologies. :)] (To be fair to Angular, we've had mobile web display bugs long before we introduced Angular.)

The infinite scrolling on the homepage, profile page, and board page is something that is now dead simple to set up, thanks to an infinite scroll directive I wrote. Also, binding site-wide follow and like buttons (and other such things) to a currentUser model means a single update in the model updates the view everywhere. Also, admin pages (for staff to manage users, featured content, etc.) have been written in record time.

We've also been able to both simplify and boost our client-side test coverage compared to the old code (which had far too much DOM access to test effectively).

Avatar

There is often a distinction made when discussing this topic that separates "web applications" and "web sites." The difference is, perhaps, a bit pedantic, but thinking about it in this way can help understand where people are coming from.

For example, Gmail would be a "single page app"--there are no page reloads, and all the content changes are handled via JavaScript. Generally your server software will only render a single view, and the client-side technology will handle moving things around.

A site like StackOverflow, however, would be classified as a "web site" (even though many might call it a web application). While it has elements that lean on JavaScript and Ajax, you still primarily browse content by browsing different URLs, which the server software renders separately.

Client-side frameworks like Angular provide special tools for building the former (Gmail-style) web applications (for example, see Angular's $routeProvider service and ngView directive), and people often focus on this because these apps can be harder to write and seem "newer" or "cooler," but Angular can be used to drive elements in a more traditionally built web site as well.

Avatar

This is a fantastic question. As I expressed in a comment below, we've been using AngularJS in production for a couple months now with huge success. However, we didn't start off using Angular--at first, we used a more "traditional" (one might say "old school") style of basic, imperative jQuery code.

While this worked, as the application's complexity grew over time, the JavaScript we had written (which I have come to term "jQuery Soup") became more and more unmaintainable. It became clear that our existing direction was not tenable in the long term; this is when I introduced AngularJS to the team.

Now, we have rewritten significant portions of our application using Angular, and things are going very well. That said, if we had started out using Angular (or another client-side framework like Ember, Knockout, Backbone, and so forth), perhaps we wouldn't have felt the JavaScript pain as early as we did, and would not have to rewrite anything.

On the flip side, sometimes these frameworks can take a bit of time to master--Angular gets a little more complex conceptually when you start getting into providers, directives, child and isolate scopes, etc. While the learning curve has proven worth it to our team now, using plain jQuery in the beginning may have allowed us to get our app out the door faster than learning a new framework like Angular would have.

So, while I would say that learning such a client-side framework is a great idea (I believe every web developer should have some proficiency with at least one), I don't think it's necessary to try to force that kind of architecture on every application you write. You have to make a judgement call and determine for yourself if you think it'll be worth it. I will say, however, that if you believe that your client-side code will grow to be even a little complex, some kind of framework is likely a good idea, and as Ryan has demonstrated so expertly here, Angular makes it really simple to build client-side apps!

Avatar

Excellent introduction to AngularJS! We've been using it fairly extensively in production (in a Rails app) for a couple months now, and it's definitely helped clean up and speed up our client-side code and development time.

Avatar

Ryan doesn't do the ASCIIcasts, that's handled by a fine fellow named Eifion Bedford. Check out his about page.