Angular 2.0

core concepts

slack.jsbelgrade.org

Dušan Stanković

Full-stack developer @ Embroker

@dulerock

me@dulerock.com

Zašto Angular 1.x?

Lak za testiranje (karma + jasmine,  protractor)

Ekspresivan

Dependency Injection

Directives

Two-way data binding

Built-in stuff (promises($q), ajax($http), jqlite...)

TO BRE!

Zašto onda Angular 2?

Performanse (change-detection, template caching...)

Web standardi (ES6, Web components...) 

Lak za razumevanje i korišćenje

Change detection

Model

Directive

DOM

(graph)

Model

Component

DOM

SLOW?

(tree)

Change detection

Monomorfni vs polimorfni kod

1 klasa po komponenti za change detection

3-10x brže

Immutable

Observable

Komponente

Komponenta

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

@Component({
    selector: 'dafed-app'
})
@View({
    template: `<h1>Dobrodosli na predavanje {{name}}</h1>`
})
class DafedApp{
    name: string;

    constructor(){
        this.name = "Angular 2.0 - core concepts";
    }
}

bootstrap(DafedApp);

Type anotacije

Meta anotacije

Komponenta (ES5)

var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") return Reflect.decorate(decorators, target, key, desc);
    switch (arguments.length) {
        case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target);
        case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0);
        case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc);
    }
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var angular2_1 = require('angular2/angular2');
var DafedApp = (function () {
    function DafedApp() {
        this.name = "Angular 2.0 - core concepts";
    }
    DafedApp = __decorate([
        angular2_1.Component({
            selector: 'dafed-app'
        }),
        angular2_1.View({
            template: "<h1>Dobrodosli na predavanje {{name}}</h1>"
        }), 
        __metadata('design:paramtypes', [])
    ], DafedApp);
    return DafedApp;
})();
angular2_1.bootstrap(DafedApp);

Komunikacija

DOM eventi umesto event na scope-u

DI

<predavanja>
  <predavanje title="Angular 2.0">...</predavanje>
  <predavanje title="ReactJS">...</predavanje>
</predavanja>
@Component({
  selector: 'predavanja'
})
@View({
 templateUrl: 'views/predavanja.html' 
})
class Predavanja {
  lista: QueryList<Predavanje>
  constructor(@Query(Predavanje) lista:QueryList<Predavanje>) {
    this.lista = lista;
  }
}

Arhitektura

1.x

2.0

Model

View

Controller

Model

View

Controller

Directive

DI: Service, Provider, Factory, Value...

Directive

View

Component

Injectable

Bindings

Element property binding

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

@Component({
    selector: 'dafed-prijava'
})
@View({
    template: `<h1>Prijavi se za Dafed</h1>
                <input type="text" [value]="defaultValue"/>
                <button [type]="buttonType">Prijavi se odmah</button>
                `
})
export class DafedComponent{
    defaultValue: string;
    buttonType: string;

    constructor(){
      this.defaultValue = "Pera Kojot";
      this.buttonType = "submit";
    }
}

Event bindings

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

@Component({
    selector: 'dafed-prijava'
})
@View({
    template: `<h1>Prijavi se za Dafed</h1>
                <button (click)="prijaviSe($event)" (obavesti)="obavestiKorisnika()">
                Prijavi se odmah</button>`
})
export class DafedPrijavaComponent{

    prijaviSe(event) {
      event.currentTarget.dispatchEvent(new Event('obavesti'));
    }

    obavestiKorisnika(){
      alert("Uspesno prijavljen");
    }
}

TWO-WAY BINDINGS

Direktive

import PassInput from './pass.js';


@Component({
  selector: 'dafed-login'
})
@View({
  template: `
    <input type="password"
           (pass-match)="onPassOk($event)">
  directives: [PassInput]
})
class DafedLogin {

  onPassOk(event) {
    alert('pass has 6 chars');
  }
}
@Directive({
  selector: 'input',
  events: ['passMatch'],
  hostListeners: { 
    keyup: 'onKeyup($event.target.value)' 
  }
})
class PassInput {

  passMatch:EventEmitter 
    = new EventEmitter();
  
  onKeyup(value) {
    if(/^[a-zA-Z0-9]{6}$/.test(value)) {
      this.passMatch.next('matched');
    }
  }
}

Dependency Injection

pre-injectors

component injectors

element injectors

PRODUCTION READY?

NOT!

Hvala!

Pitanja?

@dulerock

Angular2.0 - Core concepts

By Dušan Stanković

Angular2.0 - Core concepts

Deck for #36 DaFED

  • 1,869