Intro to Angular 2

David East / @_davideast

Full-time Firebase. Part-time Angular.

Disclaimer

Angular 2 is a work in progress.

Things might/will change.

Outline

Motivation

Concepts

Code

Angular 1 is aging

The code base for Angular dates back to 2009

Web Standards

Shadow DOM replaces Transclusion

ES6 Modules replaces Angular Modules

Peformance

"Today, Angular2 is 5x faster than Angular 1"

- Misko, 2/10/15

Deep Tree Benchmark
2015-02-09

Simple Cognitive Model

Angular 1.x has many concepts

Concepts have a learning curve

Angular 1.x Concepts

Controller

Factory

Service

Provider

Directive

Transclusion

Module

Scope

Motivation

Web Standards

Performance

Simple Cognitive Model

Angular 2

					
@Template({
  url: 'todos.html'
})
@Component({
  selector: 'todo-app',
})
class TodoApp {
  todos: string[];
  constructor() {
    this.todos = ['Item1', 'Item2'];
  }
}
					
					

TypeScript

A typed superset of JavaScript that compiles to plain JavaScript

						
@Template({
  url: 'foo.html'
})
@Component({
  selector: 'foo',
})
class Foo {
  bar: string;
  constructor() {
    this.bar = 'baz';
    this.bar = 2; // compiler throws an error
  }
}
						
					

TypeScript

Compiles to ES5/ES6

Not required for Angular 2

Types are optional

Components in ES5

						
var Foo = (function() {
  function Foo(bar) {
    this.bar = 'baz';
  }
  Foo.prototype = {};
  Foo.annotations = [
    new Component({ selector: app }),
    new Template({ url: 'todos.html' })
  ];
}());
						
					

Components

						
@Template({
  url: 'todos.html'
})
@Component({
  selector: 'todo-app',
})
class TodoApp {
  constructor() {
    this.todos = ['Item1', 'Item2'];
  }
}
						
					

Component Annotations

						
@Template({
  url: 'todos.html'
})
@Component({
  selector: 'todo-app',
})
						
					
						
<todo-app></todo-app>
						
					

Component Controller

						
class TodoApp {
  constructor() {
    this.todos = ['Item1', 'Item2'];
  }
}
						
					

Components

						
@Template({
  url: 'todos.html'
})
@Component({
  selector: 'todo-app',
})
class TodoApp {
  constructor() {
    this.todos = ['Item1', 'Item2'];
  }
}
						
					

Bootstrapping

Angular 1.x

						
var app = angular.module('app', []);
						
					
						
<body ng-app="app">

</body>
						
					
						
app.controller('MyCtrl', function($scope) {
  $scope.name = 'David';
});
						
					
						
<body ng-app="app">

  <div ng-controller="MyCtrl">
    My name is {{ name }}
  </div>

</body>
						
					

Angular 1.x

  1. Create Module
  2. Declare ng-app
  3. Create controller
  4. Attach items to $scope
  5. Declare Controller
  6. Create Template

Angular 2 Bootstrapping

Create Component

						
@Component({
  selector: 'todo-app',
})
@Template({ url: 'todos.html' })
export class TodoApp {
  todos;
  constructor() {
    this.todos = ['Item1', 'Item2'];
  }
}
						
					

bootstrap

						
import {bootstrap} from 'angular';
import {TodoApp} from 'todoapp';
bootstrap(TodoApp);
						
					

ES6/TypeScript compilation



The TypeScript compiler will compile to ES5

For ES6, use Traceur (experimental options for Annotations)

Angular 2

  1. Create Component
  2. Create Template
  3. bootstrap
  4. Transpilation

Template Syntax

						
@Template({
  url: 'name-change.html'
})
@Component({
  selector: 'name-change',
})
class NameChange {
  constructor() {
    this.name = '';
  }
  changeName(newName) {
    this.name = newName;
  }
}
						
					
						
<div> My name is {{ name }} </div>
<div>
  <input #newname type="text">
  <button (click)="changeName(newname.value)"
          [disabled]="newname.value == 'David'"> Change Name
  </button>
</div>
						
					

Local Variables

						
<div>
  <input #newname type="text">
  {{ newname.value }}
</div>
						
					

Event Handlers

						
<div>
  <input #newname type="text">
  <button (click)="changeName($event, newname.value)">
</div>
						
					

Property Bindings

						
<div>
  <input #newname type="text">
  <span [textContent]="newname.value"></span>
</div>
						
					
						
@Template({
  url: 'name-change.html'
})
@Component({
  selector: 'name-change',
})
class NameChange {
  constructor() {
    this.name = '';
  }
  changeName(newName) {
    this.name = newName;
  }
}
						
					
						
<div> My name is {{ name }} </div>
<div>
  <input #newname type="text">
  <button (click)="changeName(newname.value)"
          [disabled]="newname.value == 'David'"> Change Name
  </button>
</div>
						
					

Uniformity

(event) - for events

[property] - for properties

Change Detection

An Angular2 application is a tree of components
Victor Savkin's Blog Post

Zone.js

Informs Angular when to run change detection

No more $timeout!

						
app.controller('UserCtrl', function($scope, $timeout) {
  var ref = new Firebase('https://<my-firebase>.firebaseio.com/user/1');

  ref.on('value', function(snap) {

    $timeout(function() {
      $scope.user = snap.val();
    });

  });
});
						
					

Code!

Summary

We're working on documentation

https://angular.io

ASK ME QUESTIONS

David East / @_davideast