angularjs-logo Insights


By @PascalPrecht

#HannoverJS 24th Jan '13

Hello there.

This is me
(@PascalPrecht)

me

My neighbor.
He likes coding.
But he can't.

neoskop-logo

heartworking heart

For those who are interested...

We also play soccer!

neo-soccer

angular-shield ?

AngularJS is what HTML would have been, had it been designed for applications.

HTML enhanced for web apps!

HTML++

Great features!

Dependency Injection.

Modularization.

Testability.

Example

Hello {{name}}!



Enter your name:

The code.



<h1>Hello {{name}}!</h1>
<h3>Enter your name:</h3>
<input type="text" ng-model="name">
            

Another example

Song

Interpret

{{song.title}} {{song.artist | uppercase}}

The code.


<section> ng-controller="FilterCtrl">
  <input type="text" ng-model="search">

  <table>
    <tr>
      <td>Song</td>
      <td>Interpret</td>
    </tr>

  <tr ng-repeat="song in songs | orderBy:'title' | filter:search">
      <td>{{song.title}}</td>
      <td>{{song.artist | uppercase}}</td>
    </tr>
  </table>
</section>
            

Can't get enough?

Drag the heart!


The code.


<h2>Drag the heart!</h2>
<div draggable></div>
            

...and a bunch of other code.


app.directive('draggable', function($document) {
    var startX=0, startY=0, x = 0, y = 0;
    return function(scope, element, attr) {
      element.css({
       position: 'relative',
       cursor: 'pointer'
      });
      element.bind('mousedown', function(event) {
        startX = event.screenX - x;
        startY = event.screenY - y;
        $document.bind('mousemove', mousemove);
        $document.bind('mouseup', mouseup);
      });

      function mousemove(event) {
        y = event.screenY - startY;
        x = event.screenX - startX;
        element.css({
          top: y + 'px',
          left:  x + 'px'
        });
      }

      function mouseup() {
        $document.unbind('mousemove', mousemove);
        $document.unbind('mouseup', mouseup);
      }
    }
  });
          

Where does all the awesomeness come from?!

The Zen of Angular

  • Declarative code is better for UI's

  • Imperative code is excellent for expressing business logic

  • Decoupling DOM manipulation from app logic improves testability

..this means you don't have to care about:



  • Registering callbacks

  • Manipulating HTML DOM programmatically

  • Writing tons of initialization code just to get started

Bootstrapping an Angular app

Using ng-app



<html ng-app="optionalModuleName">
  <body>
    I can add {{ 1+2 }}.
    <script src="angular.js"></script>
  </body>
</html>
            

Behind the scenes

Manual Initialization



<html ng-app="optionalModuleName">
  <body>
    Hello {{'World'}}!
    <script src="angular.js"></script>
    <script>
      angular.element(document).ready(function () {
        angular.bootstrap(document);
      });
    </script>
  </body>
</html>
            

Step by step



window.onload = function() {
  var $rootElement = angular.element(window.document);
  var modules = [
    'ng',
    'myApp',
    function($provide) {
      $provide.value('$rootElement', $rootElement)
    }
  ];
  var $injector = angular.injector(modules);
  var $compile = $injector.get('$compile');
  var compositeLinkFn = $compile($rootElement);

  var $rootScope = $injector.get('$rootScope');
  compositeLinkFn($rootScope);

  $rootScope.$apply();
}
            

Demo

The Scope

(aka the glue)

Hello {{name}}!

Behind the scenes

Angular Runtime

Single source of truth


Oh my {{name}}!

Oh my {{name}}!

Oh my {{name}}!

Oh my {{name}}!

Oh my {{name}}!


Behind the scenes

Example: Hello world


  • ng-model and input directive set up keydown listener

  • {{name}} interpolation sets up $watch expression

  • input directive captures change to input's value and calls $apply("name = 'x';")

  • $digest loop begins

  • $watch list detects change and notifies {{name}} interpolation

  • Angular exits execution context -> exits keydown event -> exits JS execution context

  • Browser re-renders the view

Providers

(aka $provide)

Ways of getting data into your controllers

  • value

  • constant

  • service

  • factory

  • decorator

  • provider

The first time I got into this...

Srsly.

Constant


Injectable anywhere!



app.constant('HannoverJS', 'Is awesome!');
          

(This is definitely a constant)

Value


Injectable value.



app.value('hash', { foo: 'bar' });
          

Could be anything: Primitive, Hash ...

Service


Injectable constructor.



app.service('ServiceA', function (dep) { ... });
          

Singleton.

Factory


Injectable function.



  app.factory('CarFactory', function (dep) { ... return 'foo'; });
            

Actually, a provider with only a $get method.

More creating a factory then being a factory.

Provider



$provide.provider('foo', {$get: function (dep) { ... }});
$provide.provider('foo', function () {
  this.$get = function (dep) { ... };
});
            

$get method required!

Wanna get started?



What you should also check out:



Thank you!