Angular 2

Core concepts

History

- Started by Miško Hevery in 2009

 

- Challenged to migrate a project from GWT (3 devs × 6 months) to Angular in 2 weeks ....... and FAILED

 

- version 1.0 released in 2012

 

- current version is 1.6.1 (23/12/2016)

- $scope, $http, $resource, two-way binding

 

- Global API - angular.copy(), angular.equals(), -angular.bind() ...

 

- $broadcast, $emit, $watch, $eval, $digest, $apply...

 

- Directives (58 build-in)

 

- Services, Factories, Providers

Angular 2 vs 1.x

TypeScript

https://www.typescriptlang.org/

- Developed and maintained by Microsoft

 

- Open source programming language

 

- Optional static typing and class-based OOP

 

- Anders Hejlsberg, lead architect of C# and creator of Delphi and Turbo Pascal, has worked on the development of TypeScript.

Text

Text

-The TypeScript compiler is implemented in TypeScript

TypeScript = ES6 + Types + Annotations

class Animal {
    constructor(public name: string) { }
    move(distanceInMeters: number = 0) {
        console.log(`${this.name} moved ${distanceInMeters}m.`);
    }
}
class Snake extends Animal {
    constructor(name: string) { super(name); }
    move(distanceInMeters = 5) {
        console.log("Slithering...");
        super.move(distanceInMeters);
    }
}
let sam = new Snake("Sammy the Python");
sam.move();
var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Animal = (function () {
    function Animal(name) {
        this.name = name;
    }
    Animal.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) { distanceInMeters = 0; }
        console.log(this.name + " moved " + distanceInMeters + "m.");
    };
    return Animal;
}());
var Snake = (function (_super) {
    __extends(Snake, _super);
    function Snake(name) {
        return _super.call(this, name) || this;
    }
    Snake.prototype.move = function (distanceInMeters) {
        if (distanceInMeters === void 0) { distanceInMeters = 5; }
        console.log("Slithering...");
        _super.prototype.move.call(this, distanceInMeters);
    };
    return Snake;
}(Animal));
var sam = new Snake("Sammy the Python");
sam.move();

- Component-Based

- Templates

- Reduced and simplified build-in directives

(*ngIf, *ngFor, [ngSwitch], [ngSwitchCase], ngSwitchDefault, [ngClass])

- One-way data binding (two-way is also available)

- New Dependency Injection system

- Improved Change Detection System

- Native support

Angular 2

- Framework for building client applications in TypeScript and HTML

 

- Consists of several libraries

(angular/core, angular/platform-browser, angular/http, angular/forms, ...)

 

- Angular Application =

Modules[(angularized HTML + Directives) + Services]

 

- Launching the application = Bootstrap the root module

// app.component.ts
import { Component } from '@angular/core';
@Component({
  selector: 'my-app',
  template: `
    <div>
      <h1>Hello {{name}}</h1>
    </div>
  `
})
export class AppComponent { name = 'World'; }

// app.module.ts
import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
  imports:      [ BrowserModule ],
  providers:    [ Logger ],
  declarations: [ AppComponent ],
  exports:      [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

// main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);

// index.html
<body>
<my-app>Starting application...</my-app>
</body>
import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
  imports:      [ BrowserModule ],
  providers:    [ Logger ],
  declarations: [ AppComponent ],
  exports:      [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }
export class HeroListComponent implements OnInit {
  heroes: Hero[];
  selectedHero: Hero;

  constructor(private service: HeroService) { }

  ngOnInit() {
    this.heroes = this.service.getHeroes();
  }

  selectHero(hero: Hero) { this.selectedHero = hero; }
}
<h2>Hero List</h2>
<p><i>Pick a hero from the list</i></p>
<ul>
  <li *ngFor="let hero of heroes" (click)="selectHero(hero)">
    {{hero.name}}
  </li>
</ul>
<hero-detail *ngIf="selectedHero" [hero]="selectedHero"></hero-detail>
@Component({
  moduleId:     module.id,
  selector:    'hero-list',
  templateUrl: 'hero-list.component.html',
  providers:  [ HeroService ]
})
export class HeroListComponent implements OnInit {
/* . . . */
}
<li *ngFor="let hero of heroes"></li>
<hero-detail *ngIf="selectedHero"></hero-detail>

Structural

Attributes

// highlight.directive.ts
import { Directive, ElementRef, Input } from '@angular/core';
@Directive({ selector: '[highlight]' })
export class HighlightDirective {
    constructor(el: ElementRef) {
       el.nativeElement.style.backgroundColor = 'yellow';
    }
}
// page.html
<p highlight>Highlight me!</p>
// app/logger.service.ts

@Injectable() 
export class Logger {
  log(msg: any)   { 
    console.log(msg); 
  }
  error(msg: any) { 
    console.error(msg); 
  }
  warn(msg: any)  { 
    console.warn(msg); 
  }
}
// app.module.ts
@NgModule({
  imports:      [ ... ],
  providers:    [ Logger ],
  exports:      [ ... ],
  bootstrap:    [ ... ]
})
export class AppModule { 

}
// app/hero-list.component.ts

@Component({
  selector:    'hero-list',
  templateUrl: 'hero-list.component.html',
  providers:  [ HeroService ]
})
export class HeroListComponent {
  constructor(private service: HeroService) { 
  }
}
// hero-list.component.html
<li>{{hero.name}}</li>

<hero-detail [hero]="selectedHero"></hero-detail>

<li (click)="selectHero(hero)"></li>

// hero-detail.component.html
<input [(ngModel)]="hero.name">


// --- understanding ngModel ---
<input [ngModel]="hero.name" (ngModelChange)="hero.name = $event">

Application state change is caused by three things:

 

Events - User events like click, change, input, submit, …

 

XMLHttpRequests - E.g. when fetching data from a remote service

 

Timers - setTimeout(), setInterval(), because JavaScript

ObservableWrapper.subscribe(this.zone.onTurnDone, () => {
  this.zone.run(() => {
    this.tick();
  });
});

tick() {
  // perform change detection
  this.changeDetectorRefs.forEach((detector) => {
    detector.detectChanges();
  });
}

Change detection

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush
}) 
export class ImmutableTodoCmp { 
  ...
}
// todos.component.ts

type ObservableTodo = Observable<todo>; 
type ObservableTodos = Observable<array>>; 

@Component({
  selector: 'todos',
  template: `<todo *ngFor="let t of todos" todo="t"></todo>`
}) 
class ObservableTodosCmp { 
  todos:ObservableTodos; 
  ... 
}


// todo.component.ts

@Component({selector:'todo'}) 
class ObservableTodoCmp { 
  todo: ObservableTodo; 
  ... 
}

Resources

https://angular.io/

http://learnangular2.com/

http://blog.ng-book.com/

https://angular.io/docs/ts/latest/guide/cheatsheet.html

https://dzone.com/articles/typed-front-end-with-angular-2

http://angular2academy.com/2017/01/08/angular-2-core-components/

https://blog.thoughtram.io/angular/2016/02/01/zones-in-angular-2.html

https://vsavkin.com/change-detection-in-angular-2-4f216b855d4c#.tigfnjcvx

https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html

 

https://egghead.io/courses/angular-2-fundamentals

http://courses.angularclass.com/p/angular-2-fundamentals

Thank you!

Angular 2. Core concepts

By Stanislav Oaserele

Angular 2. Core concepts

  • 868