Sergey Danilov

web developer at Fleetmatics

Angular 2.0 - first look

The Angular is dead,

long live the Angular!

History

ng-europe 2014

Let's kill everything

angular.module and jqLite

are killed as well

- Controllers are gone

- Directives are dead

- Rip $scope

Foundation Angular 2.0

AtScript (super set of ES6)

Annotations

Generic binding syntax

DI mechanism based on types

Everything is Component

    // Annotation / decorators section
    @Component({
      selector: 'my-app'
    })
    @View({
      template: '<h1>Hello {{ name }}</h1>'
    })
    // Component controller
    class MyAppComponent {
      name: string;
      
      constructor() {
        this.name = 'Alice';
      }
    }

Latest news :)

Performance

and

Rendering

Deep Tree Benchmark: Render

Deep Tree Benchmark: Memory

Angular 2 in a Web Worker

Main

Worker

Angular

DOM

Render

Angular

App

Render separation

Worker

Angular

Render

Angular

App

... like ReactNative

Server-side Angular

Faster Startup

SEO

Preview

New syntax in templates

more details on ng-conf 2015 (Misko Hevery)

Property bindings


    <todo-cmp [model]="todoItem"></todo-cmp>

Event bindings


    <todo-cmp (complete)="onComplete()"></todo-cmp>
@Component({
  selector: 'todo-cmp',
  events: ['complete']
})
class TodoCmp {
  constructor() {
    this.complete = new EventEmitter();
    // EventEmitter is an implementation of both
    //    the observable and observer interfaces
  }
  onComplete() {
    this.complete.next(); // this fires an event
  }
}

Two-way bindings

    
    <input [ng-model]="todo.text" (ng-model)="todo.text=$event"></input>

    <input [(ng-model)]="todo.text"></input>

or

@Directive({
  selector: '[ng-model]',
  properties: ['ngModel'],
  events: ['ngModelChanged: ngModel'],
  host: {
    "[value]": 'ngModel',
    "(input)": "ngModelChanged.next($event.target.value)"
  }
})
class NgModelDirective {
  ngModel:any; // stored value
  ngModelChanged:EventEmitter; // an event emitter
}

Templates, * and local vars

    
    <todo-cmp *ng-for="#item of todos; #i=index" [model]="item" [index]="i"></todo-cmp>
<todo-cmp template="ng-for #item of items; #i=index" [model]="item" [index]="i"></todo-cmp>

this de-sugars it into

which de-sugars into

    
    <template ng-for #item="$implicit" [ng-for-of]="items" #i="index">
          <todo-cmp [model]="item" [index]="i"></todo-cmp>
    </template>

Annotations / Decorators


    import { Component, View } from 'angular2/angular2';

    @Component({
      selector: 'my-app'
    })
    @View({
      template: '<h1>Hello world</h1>'
    })
    class MyAppComponent {
      constructor() {
      }
    }

Annotations


    var MyAppComponent = (function () {
      function MyAppComponent () {}
    
      MyAppComponent.annotations = [
        new Component({...}),
        new View({...})
      ];
    
      return MyAppComponent;
    })();

transpiler should know how transform it

Decorators


    // A simple decorator
    @annotation
    class MyClass { }



    function annotation(target) {
       // Add a property on target
       target.annotated = true;
    }

for now angular 2.0

(it seems from alpha 22)

use decoraters

and all transpilers has extensions for it or support it out of the box (Typescript 1.5)

Change Detection 

An Angular 2 application is a tree of components

An Angular 2 application is a reactive system

and it has tree of change detectors

Strategies of optimizations

- Immutable objects

- Observable objects

Immutable objects

Disabled change detection

Setup change detection strategy

    
    @Component({changeDetection:ON_PUSH})
    class ImmutableTodoCmp {
      todo:Todo; 
    }

Observable objects

 The first pass

Fire an event

Next pass

  • App_ChangeDetector
  • Todos_ChangeDetector
  • the first Todo_ChangeDetector

Declaration

    
  type ObservableTodo = Observable<Todo>;

  type ObservableTodos = Observable<Array<ObservableTodo>>;

Cooking Angular 1 for second version


    angular
        .module('app', [])
        .controller('MyController', ['$scope',
        function ($scope) {
            // some methods
            $scope.doSomething = function() { ... }
        }
    ]);
    

    <div ng-controller="MyController">
        ...
        <button ng-click="doSomething()">Do It</button>
    </div>

"controller as" syntax


    angular
        .module('app', [])
        .controller('MyController', ['$scope',
        function ($scope) {
            var vm = this;
            // some methods
            vm.doSomething = function() { ... }
        }
    ]);
    
    

    <div ng-controller="MyController as ctrl">
        ...
        <button ng-click="ctrl.doSomething()">Do It</button>
    </div>

Using  $inject and hoisting 


    angular
        .module('app', [])
        .controller('MyController', MyController);

    MyController.$inject = ['$scope'];

    function MyController($scope) {
        var vm = this;
        // some methods
        vm.doSomething = function() { ... }
    }
    
    

    <div ng-controller="MyController as ctrl">
        ...
        <button ng-click="ctrl.doSomething()">Do It</button>
    </div>

Independent declaration & ES6


    import MyController from './my-controller.js'

    angular
        .module('app', [])
        .controller('MyController', MyController);
    
    class MyController {
        constructor($scope) {
            ...
        }

        doSomething () { ... }
    }

    MyController.$inject = ['$scope'];

    export default MyController;

Real Angular 2 component from demo

    
@Component({
    selector: 'todo-list',
    properties: ['list']
})
@View({
    templateUrl: 'src/components/todo-list.template.html',
    directives: [NgFor, NgIf, NgModel, TodoItem]
})
class TodoList {
    constructor(store){
        this.store = store;
    }
    
    ...

    clearCompleted() {
        this.store.clearCompletedItems();
    }
}

TodoList.parameters = [[TodoStore]];

export default TodoList

Vanilla Angular 1

Angular 1 + ReactJS

Angular 1 + React vs Angular 2

Sources

Do you have any questions?

Next Milestones

Finish Core

API Sugaring

Perf +

Docs

Migration support

Animate

Material Design

CLI

Server Render

Native

Web Workers

?

Local variables

    
    <video-player #player></video-player>
    
    <video-player var-player></video-player>

is shugar sintax for

    
    <button (click)="player.pause()">Pause</button>

using it in other place