Beyond
ng-hello-world

Building Real World
Web Apps with AngularJS

by Rob Friesel

What are we talking about?

  • open source
  • from Google
  • for building complex web apps
...a toolset for building the framework most suited to your application development.

What are we not talking about?

  • "the basics"
  • comprehensive feature coverage
  • side-by-side comparisons
  • pros/cons of single-page apps

AngularJS

a lightning tour

MVW1!

1: "M-V-Whatever"

Customary Features!

  • declarative data-binding
  • client-side controllers
  • separation of concerns

Opinionated in the Middle

a trivial example

The Angular Way

"lethally allergic to global state"

"Hands off the DOM."

"extend HTML vocabulary"

The Mechanics

  • Controllers & $scope
  • Services
  • Filters
  • Directives

controllers & $scope

example controller


angular.module('books').controller('BookListController', [
  // set up dependency injection:
  '$scope', '$window',
  // controller (DI through function arguments)
  function($scope, $window) {
    $scope.books = $window.BOOKS;

    $scope.getStarClass = function(rating, compare) {
      return 'glyphicon glyphicon-star' +
        ((rating > compare) ? '' : '-empty');
    };

    // and so on
  }
]);
            

...and hook it up


<!DOCTYPE html>
<html lang="en" ng-app="books">

  <body>
    <div ng-controller="BookListController">
      <table>
        <tr ng-repeat="book in books">
          <td>{{book.title}}</td>
          <td>{{book.author}}</td>
          <td>{{book.rating}}</td>
        </tr>
      </table>
    </div>
  </body>

</html>
            

roughly illustrated

Services

example service


angular.module('books').factory('goodreadsService', ['$http',
  function($http) {
    function getShelf(userId, shelf) {
      return $http.get(GOODREADS_HOST + REVIEWS_LIST, {
        params: {
          v: 2, key: API_KEY,
          id: userId, shelf: shelf
        }
      });
    }

    return {
      getShelf: getShelf
    };
  }
]);
            

Filters

example filter


angular.module('books').filter('dropSubTitle', [
  function() {
    return function(input, token) {
      return input.split(token || ':')[0];
    };
  }
]);
            

...and using it


<ul>
  <li ng-repeat="book in books">
    <em ng-bind="book.title | dropSubTitle:'-'"></em> by
    <span ng-bind="book.author"></span>
  </li>
</ul>
            

Directives

example directive


angular.module('books').directive('grRating', [
  function() {
    return {
      replace: true,
      restrict: 'AC',
      templateUrl: '/ng-templates/gr-rating',
      scope: { rating: '=' },
      link: function(scope, element, attrs) {
        scope.getStarCss = function(compare) {
          return 'glyphicon-star' +
            ((scope.rating > compare) ? '' : '-empty';
        };
      }
    };
  }
]);
            

/ng-templates/gr-rating


<div>
  <span class="glyphicon" ng-class="getStarCss(0)"></span>
  <span class="glyphicon" ng-class="getStarCss(1)"></span>
  <span class="glyphicon" ng-class="getStarCss(2)"></span>
  <span class="glyphicon" ng-class="getStarCss(3)"></span>
  <span class="glyphicon" ng-class="getStarCss(4)"></span>
</div>
            

using that directive


<div ng-controller="BookListController">
  <ul>
    <li ng-repeat="book in books">

      <!-- and our directive: -->
      <span gr-rating data-rating="book.rating"></span>

    </li>
  </ul>
</div>
            

...and much more!

  • core APIs
  • jqLite
  • routes
  • $apply, $digest, and $watch...
  • testing

Tripoli

a case study

real quick:

What is Tripoli?

...leveraging ZooKeeper, we at Dealer.com have built a centralized, remote configuration service that provides consistent, flexible and accountable configurations to applications in our enterprise.

Tripoli is the front-end for that

Let's have a quick look...

Why Angular?

Separation of Concerns

Idiomatic

Velocity

Modules

Great Developer Community

...and getting better all the time

"It's just JavaScript!"

Testable

Difficulties, Hitches, Pitfalls, Problems, and Other Realities

Documentation

Not Actually That Great

Examples

Not Always the Safest

Bad Example


// taken right from the AngularJS home page...
function TodoCtrl($scope) {
  $scope.todos = [ /*todos...*/ ];
  // etc.
}
            

"Where do I begin?"

Whither Animation?

$apply and the $digest

"slippery scope"

Temptation to Fight the Framework

Putting It All Together

Be Conservative with Controllers

Be Liberal with Directives

Organize Your Code Early

Example Angular File Organization


web-app/
  js/
    ng-app-base.js
    controllers/
      ExampleController.js
    directives/
      ngxDirective.js
    filters/
      filterName.js
    services/
      exampleService.js
    lib/
templates/
  _ngxDirective
            

Questions?

Thanks!