Angular 2 

Abhishek Agashe

Components

import {Component} from 'angular2/angular2';

//Metadata annotation
@Component({
	selector: 'app',
	template: `
            <div>
                <h1>{{greetings}} everybody </h1>   
                    <!-- Welcome everybody --!>
                <p class='red' bold> Happy holidays !!! </p>
            </div>
        `,
	styles: [`
		.red: {color: red}
		`]
})

export class App {
        greetings: string;
	constructor() {
                this.greetings: "Welcome";
	}

        onInit() {
            //Do something.
        }
}

Lifecycle hooks

  • onInit
  • afterViewInit
  • onDestroy
  • onChanges
  • doCheck
  • afterContentInit
  • afterViewChecked
import {Component} from 'angular2/angular2';
import {EmployeeList} from './employeelist';

@Component({
  selector: 'factory',
  directives: [EmployeeList],
  template: 
   `<div> 
      <h1>Factory component</h1>
      <employeelist [startwith]='filter'>
      </employeelist>
   </div>`
})

export class Factory {
    filter: string = '';
    constructor() {
        this.filter = 'C';
    }
}
import {Component, Input, NgFor} 
        from 'angular2/angular2';

@Component({
  selector: 'employeelist',
  directives: [NgFor],
  template: 
  `<div> 
      <ul>
         <li *ng-for="#employee of employeeList">
             {{employee}}
         </li>
      </ul>
   </div>`
})

export class EmployeeList {
    @Input() startwith: string;

    employeeList: string[];
    myEmployees: string[] = ['C-3PO','Darth Vader', 
                            'Han Solo','Chewbacca', 
                            'Yoda','Count Dooku'];
    constructor() {
    }
    onInit() {
        this.employeeList = this.myEmployees.filter(
         (employee)=>{
            return employee.startsWith(this.startwith);
         });
    }
}

Data binding between components

Factory

Employee List

<div> 
      <h1>App component</h1>
      <ul>
          <li>C-3PO</li>
          <li>Chewbacca</li>
          <li>Count Dooku</li>    
      <ul>
   </div>
@Component({
  selector: 'eventemitter',
  template: 
   `<div> 
      <h1>Event Emitter Component</h1>
      <button (click)="clicker($event)">
         Click me 
      </button>
   </div>`
})

export class App {
  @Output clicked: EventEmitter 
                  = new EventEmitter();

  clicker(event) {
    this.clicked.next(event.target.value);
  }
}

Events / Custom Events

@Component({
  selector: 'app',
  directives: [eventemitter]
  template: 
   `<div> 
      <h1>My component</h1>
        <eventemitter (clicked)="handleClick($event)">
        </eventemitter>
     
   </div>`
})

export class App {

    handleclick(value) {
       console.log(value);
    }
}

Parent component

Child component

View Encapsulation

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

@component({
    selector: 'app',
    template: `<p class="green">`,
    style: [` 
            .green { color: green}
        `],
    encapsulation: 'ViewEncapsulation.Native'
                            // .Emulated .None
})

export class App { 

       constructor() {}
}
  1. ViewEncapsulation.Emulated
    • ​angular2 view encapsulation enabled // default
  2. ViewEncapsulation.None
    • No view encapsulation​
  3. ViewEncapsulation.Native
    • ​view encapsulation using shadow dom

 

Directives


import {Directive, ElementRef} from 'angular2/angular2';

@Directive({
	selector: '[bold]'
})

export class BoldDirective {
	constructor(el: ElementRef) {
		el.nativeElement.style.fontWeight = 'bold';
	}
}
<div class="myapp">
    <p bold> Hello world </p>
</div>

Dependency Injection

class Vehicle {
    constructor() {
        var engine = new Engine();
            engine.build();
    }
}


Constructor injection

class Vehicle {
    constructor(engine: Engine) {
            engine.build();
    }
}



class Engine {
    constructor(nutsNBolts: NutsNBolts) {
            nutsNBolts.fit();
    }
}



class NutsNBolts {
    constructor() {
    .....
    }
    fit() {

    }
}



new Vehicle(new Engine(new NutsNBolts()));


// Parent component

import {Component} from 'angular2/angular2';
import {Bootstrap} from 'angular2/angular2';
import {UserService} from './userservice.js';

@Component({ template: `<div> My App </div>` ... })

export class App {
    constructor() {
     
    }
}
 
Bootstrap(App,[UserService]); //UserService available in entire app.



//Child component                                   

import {Component} from 'angular2/angular2';   
import {UserService} from './userservice.js';                          
...                                                                           
                                                                      
@Component({ ... })                                                      

export class SomeComponent {
    constructor(user: UserService) {  //Singleton 
        user.dosomething();    
    }
}

Global Injection

By default all objects injected are singleton

// parent.ts  -- parent component
import {RoutineService} from './componentservice';
import {Child} from './child';

@Component({
    ......
    template: `<div>Parent component  <child></child> </div>`,
    directives: [Child]
    providers: [RoutineService]
//    viewProviders: [RoutineService]
})

export class App {
    constructor(routineservice: RoutineService) {
         routineservice.addRoutine(["eat", "sleep", "code"]);
    }
}
//child.ts -- child component                                   

import {RoutineService} from './routineservice.js';
                                                                                                                                              
@Component({ 
    selector: 'child',
    template `<p> I am child component </p>`
})                                                      

export class SomeComponent {
    constructor(routineservice: RoutineService) {  //Singleton 
        routineservice.deleteRoutine(["sleep"]);    
    }
}

Component level injection

PIPES

<!-- Date PIPE --!>

<p>{{date | date:'mediumDate'}}</p>
    <!-- Sep 1, 2015 --!>
<p>{{date | date:'yMMMMd'}}</p>
    <!-- September 1, 2015 --!>
<p>{{date | date:'shortTime'}}</p>
    <!-- 3:50 pm --!>


<!-- CURRENCY PIPE --!>

<p>{{43 | currency: 'USD' : true}}</p>
    <!-- $43 --!>
<p>{{43 | currency: 'USD' : true : '2.2'}} </p>
    <!--$43.00 --!>
<p>{{43 | currency: 'USD' : true : '3.3'}} </p>
     <!--$043.000 --!>

Angular2 inbuilt pipes

  • currency
  • date
  • uppercase
  • json
  • limitTo
  • lowercase
  • orderBy
  • filter
  • async
  • decimal
  • percent
  • number

Async Pipes

@Component({
    template: 
    `
        <div>
             <h1>My Component </h1>
             This component is ... {{lazydata | async}}
        </div>
    `
});


export class App{
    lazyData: Promise<string> = null;

    constructor() {
        this.lazyData =  new Promise<string>((resolve: any, reject: any) => {
                                setTimeout(()=> resolve("lazy"), 3000);
                            })        
    }
}    

Async pipe also works with Observables.

Async calls

  • Http calls return observables.
  • Observable is of a love child of Promise and collection/set
  • Observable is alias to RxJs Observable
  • Rxjs is reactive programming libraray
import {Http} from 'angular2/angular2';
import {Earthquake} from '../models/earthquake';

class EarthquakeService() {
    .
    .
    .
    
    getEarthquakeData(callback:(data: any[]) => void) {
    
      this.http.get('http://earthquake-report.com/feeds/recent-eq?json')
    
    	    .map((response: any) => {
    	        return response.json();
    	    })
    
    	    .map((jsonData: any[]) => {
    		jsonData.forEach((item) => {
    	            this.earthquakeData.push(new Earthquake(item));
    		});
    		return this.earthquakeData;
    				
    	    })
    
    	    .subscribe(
    		(data:any) => callback(this.earthquakeData), //OnNext
    		(err:any)  => console.log(err),              //OnError
    		() => console.log("call completed")          //OnComplete
    	    );
    	}
    }
}

References

  • http://blog.thoughtram.io
  • http://angularconnect.com/sessions
  • https://angular.io
  • https://disqus.com/home/forum/victorsavkinsblog
  • https://github.com/abhishek-agashe/angular2-playground

 

?

deck

By abhishek_agashe