build better apps with angular 2 - day - frontend · pdf file•denotes an optional value...
TRANSCRIPT
![Page 1: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/1.jpg)
Build Better Appswith Angular 2
![Page 2: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/2.jpg)
Understand how to compose multiple, non-trivial features in Angular 2
![Page 3: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/3.jpg)
Agenda
Routing
Component Composition
Directives
Forms
Server Communication
Pipes
![Page 4: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/4.jpg)
The Demo Application• A RESTFUL master-detail web application that
communicates to a local REST API using json-server • We will be building out a widgets feature • Feel free to use the existing code as a reference point • Please explore! Don't be afraid to try new things!
![Page 5: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/5.jpg)
![Page 6: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/6.jpg)
http://bit.ly/fem-ng2-rest-app
![Page 7: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/7.jpg)
http://onehungrymind.com/fem-examples/
![Page 8: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/8.jpg)
Challenges• Using the items feature as a reference, create the file
structure for a widgets feature
![Page 9: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/9.jpg)
Router
![Page 10: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/10.jpg)
Router• Component Router • Navigating Routes • Route Parameters • Query Parameters • Child Routes
![Page 11: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/11.jpg)
Component Router• Import ROUTE_PROVIDERS, ROUTE_DIRECTIVES, and
the RouteConfig decorator • Set a base href in the head tag of your HTML like so:
<base href="/"> • Configuration is handled via a decorator function
(generally placed next to a component) by passing in an array of route definition objects
• Use the router-outlet directive to tell Angular where you want a route to put its template <router-outlet></router-outlet>
![Page 12: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/12.jpg)
@RouteConfig([ {path: '/home', name: 'Home', component: HomeComponent, useAsDefault: true}, {path: '/about', name: 'About', component: AboutComponent}, {path: '/experiments', name: 'Experiments', component: ExperimentsComponent}]) export class AppComponent {}
@RouteConfig
![Page 13: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/13.jpg)
<div id="container"> <router-outlet></router-outlet> </div>
RouterOutlet
![Page 14: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/14.jpg)
Navigating Routes• Add a routerLink attribute directive to an anchor tag • Bind it to a template expression that returns an array of
route link parameters <a [routerLink]="['Users']"> Users</a>
• Navigate imperatively by importing Router, injecting it, and then calling .navigate() from within a component method
• We pass the same array of parameters as we would to the routerLink directive this._router.navigate( ['Users'] );
![Page 15: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/15.jpg)
<div id="menu"> <a [routerLink]="['/Home']" class="btn">Home</a> <a [routerLink]="['/About']" class="btn">About</a> <a [routerLink]="['/Experiments']" class="btn">Experiments</a> </div>
RouterLink
![Page 16: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/16.jpg)
export class App { constructor(private _router: Router) {} navigate(route) { this._router.navigate([`/${route}`]); }}
Router.navigate
![Page 17: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/17.jpg)
Query Parameters• Denotes an optional value for a particular route • Do not add query parameters to the route definition
{ path:'/users', name: UserDetail, component: UserDetail }
• Add as a parameter to the routerLink template expression just like router params: <a [routerLink]="['Users', {id: 7}]"> {{user.name}} </a>
• Also accessed by injecting RouteParams into a component
![Page 18: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/18.jpg)
<div> <button [routerLink]="['./MyComponent', {id: 1}]"> My Component Link</button> <button [routerLink]="['./AnotherComponent', {queryParam: 'bar'}]"> Another Component Link</button> </div>
QueryParam
![Page 19: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/19.jpg)
import { Component } from 'angular2/core'; import { RouteParams } from 'angular2/router'; @Component({ selector: 'my-component', template: `<h1>my component ({{routeParams.get('id')}})!</h1> ̀}) export class MyComponent { constructor(routeParams: RouteParams) { this.routeParams = routeParams; }}
RouteParams
![Page 20: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/20.jpg)
Child Routes• Ideal for creating reusable components • Components with child routes are “ignorant” of the
parents’ route implementation • In the parent route config, end the path with /… • In the child config, set the path relative to the parent
path • If more than one child route, make sure to set the
default route
![Page 21: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/21.jpg)
@RouteConfig([ { path:'/another-component/...', name: 'AnotherComponent', component: AnotherComponent }]) export class App {}
@RouteConfig([ { path:'/first', name: 'FirstChild', component: FirstSubComponent }]) export class AnotherComponent {}
Child Routes
![Page 22: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/22.jpg)
Demonstration
![Page 23: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/23.jpg)
Challenges• Create a route to the widgets feature • Use routeLink to navigate to the widgets feature • Create a method in the items component that
imperatively navigates to that route • Add both route parameters and query parameters to
the widgets route
![Page 24: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/24.jpg)
Component Composition
![Page 25: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/25.jpg)
Component Composition• Component System Architecture • Clear contract with @Input and @Output • @Input • @Output • Smart Components and Dumb Components • View Encapsulation
![Page 26: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/26.jpg)
Angular History Lesson
![Page 27: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/27.jpg)
Hello Angular 1.x
![Page 28: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/28.jpg)
Let's Get Serious
![Page 29: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/29.jpg)
Let's Get Realistic
![Page 30: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/30.jpg)
Two Solid Approaches
![Page 31: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/31.jpg)
Named Routes
![Page 32: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/32.jpg)
Directives
![Page 33: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/33.jpg)
Components
![Page 34: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/34.jpg)
Component System Architecture• Components are small, encapsulated pieces of
software that can be reused in many different contexts • Angular 2 strongly encourages the component
architecture by making it easy (and necessary) to build out every feature of an app as a component
• Angular components contain their own templates, styles, and logic so that they can easily be ported elsewhere
![Page 35: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/35.jpg)
Data Binding
![Page 36: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/36.jpg)
Custom Data Binding
![Page 37: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/37.jpg)
Component Contracts• Represents an agreement between the software
developer and software user – or the supplier and the consumer
• Inputs and Outputs define the interface of a component • These then act as a contract to any component that
wants to consume it • Also act as a visual aid so that we can infer what a
component does just by looking at its inputs and outputs
![Page 38: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/38.jpg)
Component Contract
![Page 39: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/39.jpg)
<div> <item-detail (saved)="saveItem($event)" (cancelled)="resetItem($event)" [item]="selectedItem">Select an Item</item-detail> </div>
Component Contract
![Page 40: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/40.jpg)
@Input• Allows data to flow from a parent component to a child
component • Defined inside a component via the @Input decorator:
@Input() someValue: string; • Bind in parent template: <component
[someValue]="value"></component> • We can alias inputs: @Input('alias') someValue: string;
![Page 41: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/41.jpg)
import { Component, Input } from 'angular2/core'; @Component({ selector: 'my-component', template: ` <div>Greeting from parent:</div> <div>{{greeting}}</div> ̀}) export class MyComponent { @Input() greeting: String = 'Default Greeting'; }
@Input
![Page 42: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/42.jpg)
import { Component } from 'angular2/core'; import { MyComponent } from './components/my.component'; @Component({ selector: 'app', template: ` <my-component [greeting]="greeting"></my-component> <my-component></my-component> `, directives: [ MyComponent ]}) export class App { greeting: String = 'Hello child!'; }
@Input
![Page 43: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/43.jpg)
@Output• Exposes an EventEmitter property that emits events to
the parent component • Defined inside a component via the @Output decorator:
@Output() showValue: new EventEmitter<boolean>; • Bind in parent template: <cmp
(someValue)="handleValue()"></cmp>
![Page 44: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/44.jpg)
import { Component, Output, EventEmitter } from 'angular2/core'; @Component({ selector: 'my-component', template: `<button (click)="greet()">Greet Me</button> ̀}) export class MyComponent { @Output() greeter: EventEmitter = new EventEmitter(); greet() { this.greeter.emit('Child greeting emitted!'); }}
@Output
![Page 45: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/45.jpg)
@Component({ selector: 'app', template: ` <div> <h1>{{greeting}}</h1> <my-component (greeter)="greet($event)"></my-component> </div> `, directives: [MyComponent]}) export class App { greet(event) { this.greeting = event; }}
@Output
![Page 46: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/46.jpg)
Smart and Dumb Components• Smart components are connected to services • They know how to load their own data, and how to
persist changes • Dumb components are fully defined by their bindings • All the data goes in as inputs, and every change comes
out as an output • Create as few smart components/many dumb
components as possible
![Page 47: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/47.jpg)
export class ItemsList { @Input() items: Item[]; @Output() selected = new EventEmitter(); @Output() deleted = new EventEmitter();}
Dumb Component
![Page 48: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/48.jpg)
export class App implements OnInit { items: Array<Item>; selectedItem: Item; constructor(private itemsService: ItemsService) {} ngOnInit() { } resetItem() { } selectItem(item: Item) { } saveItem(item: Item) { } replaceItem(item: Item) { } pushItem(item: Item) { } deleteItem(item: Item) { }}
Smart Component
![Page 49: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/49.jpg)
View Encapsulation• Allows styles to be scoped only to one single component • There are three types of view encapsulation in Angular 2 • ViewEncapsulation.None: styles are global like any other
HTML document • ViewEncapsulation.Emulated: style scope is mimicked by
adding attributes to the elements in each components’ template
• ViewEncapsulation.Native: uses the Shadow DOM to insert styles
![Page 50: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/50.jpg)
Demonstration
![Page 51: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/51.jpg)
Challenges• Create a dumb widgets-list and item-details
component using @Input and @Output • Create a widgets service and hardcode a widgets
collection • Consume the collection in the widgets component and
pass it to the widgets-list component • Select a widget from the widgets-list • Display the selected widget in item-details
![Page 52: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/52.jpg)
Directives
![Page 53: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/53.jpg)
Directives• What is a Directive? • Attribute Directives • Structural Directives • Custom Directives • Accessing the DOM
![Page 54: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/54.jpg)
What is a Directives?• A directive is responsible for modifying a dynamic
template • A component is a specific kind of directive with a
template • For the sake of conversation… a directive is a
component without a template
![Page 55: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/55.jpg)
Structural and Attribute Directives
![Page 56: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/56.jpg)
Creating a Directive
![Page 57: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/57.jpg)
Creating a Structural Directive
![Page 58: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/58.jpg)
Accessing the DOM• First import ElementRef: import { ElementRef } from
'angular2/core' • Then inject it into the directive class constructor:
constructor(el: ElementRef) {} • Access properties directly on the directive’s DOM
element by using element.nativeElement.property: el.nativeElement.style.backgroundColor = 'yellow';
or el.nativeElement.innerText = 'Some Text';
![Page 59: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/59.jpg)
export class FemBlinker { constructor(private _element: ElementRef) { let interval = setInterval(() => { let color = _element.nativeElement.style.color; _element.nativeElement.style.color = (color === '' || color === 'black') ? 'red' : 'black'; }, 300); setTimeout(() => { clearInterval(interval); }, 10000); }}
Accessing the DOM
![Page 60: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/60.jpg)
Demonstration
![Page 61: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/61.jpg)
Challenges• Pending
![Page 62: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/62.jpg)
Forms
![Page 63: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/63.jpg)
Forms• ngModel • ngSubmit • FormBuilder • Validation
![Page 64: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/64.jpg)
ngModel• Implements Angular’s two-way binding syntax e.g.
[(ngModel)] • One of the few directives that actually uses two-way
data binding • Allows us to bind inputs to a model defined by an
interface in TypeScript Interface: export interface User { id: number; name: string; };
• Component: class UserCmp { user: User } • HTML: <input type="text" [(ngModel)]="user.name" />
![Page 65: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/65.jpg)
Binding data to an Input
![Page 66: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/66.jpg)
Getting an Input's State
![Page 67: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/67.jpg)
Get State from a Group of Inputs
![Page 68: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/68.jpg)
Leveraging formControls and formGroups
![Page 69: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/69.jpg)
FormBuilder
![Page 70: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/70.jpg)
ngSubmit• Just like any other event binding • Binds to the native submit event (generally by clicking
a button with type of submit or by pressing enter) • When form is submitted, calls whatever component
method we pass it
![Page 71: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/71.jpg)
Submitting a Form
![Page 72: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/72.jpg)
Validation• Set a local template variable to the value ngForm • Angular resets the local template variable to the
ngControl directive instance. In other words, the local template variable becomes a handle on the ngControl object for this input box.
<input type="text" required [(ngModel)]="user.name" ngControl="name" #name="ngForm" > <div [hidden]="name.valid || name.pristine" class="alert alert-danger">Name is required</div>
![Page 73: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/73.jpg)
Custom Validators
![Page 74: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/74.jpg)
Challenges• Create a form for widget-details • Bind the form to a widget object sent in via @Input • Submit the details of the form to the parent component • BONUS Add in a custom validator
![Page 75: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/75.jpg)
Server Communication
![Page 76: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/76.jpg)
Server Communication• The HTTP Module • Methods • Observable.toPromise • Error Handling • Header
![Page 77: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/77.jpg)
The HTTP ModuleSimplifies usage of the XHR and JSONP APIs API conveniently matches RESTful verbs Returns an observable
![Page 78: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/78.jpg)
The HTTP Module Methodsrequest: performs any type of http request get: performs a request with GET http method post: performs a request with POST http method put: performs a request with PUT http method delete: performs a request with DELETE http method patch: performs a request with PATCH http method head: performs a request with HEAD http method
![Page 79: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/79.jpg)
loadItems() { return this.http.get(BASE_URL) .map(res => res.json()) .toPromise();} createItem(item: Item) { return this.http.post(`${BASE_URL}`, JSON.stringify(item), HEADER) .map(res => res.json()) .toPromise();}
HTTP Methods
![Page 80: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/80.jpg)
updateItem(item: Item) { return this.http.put(`${BASE_URL}${item.id}`, JSON.stringify(item), HEADER) .map(res => res.json()) .toPromise();} deleteItem(item: Item) { return this.http.delete(`${BASE_URL}${item.id}`) .map(res => res.json()) .toPromise();}
HTTP Methods
![Page 81: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/81.jpg)
What is an Observable• A lazy event stream which can emit zero or more
events • Composed of subjects and observers • A subject performs some logic and notifies the
observer at the appropriate times
![Page 82: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/82.jpg)
Observable vs Promise• Observables are lazy – they do not run unless
subscribed to while promises run no matter what • Observables can define both setup and teardown
aspects of asynchronous behavior • Observables are cancellable • Observables can be retried, while a caller must have
access to the original function that returned the promise in order to retry
![Page 83: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/83.jpg)
Observable.subscribeWe finalize an observable stream by subscribing to it The subscribe method accepts three event handlers onNext is called when new data arrives onError is called when an error is thrown onComplete is called when the stream is completed
![Page 84: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/84.jpg)
source.subscribe( x => console.log('Next: ' + x), err => console.log('Error: ' + err), () => console.log('Completed'));
Observable.subscribe
![Page 85: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/85.jpg)
Observable.toPromiseDiving into observables can be intimidating We can chain any HTTP method (or any observable for that matter) with toPromise Then we can use .then and .catch to resolve the promise as always this.http.get('users.json') .toPromise() .then(res => res.json().data) .then(users => this.users = users) .catch(this.handleError);
![Page 86: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/86.jpg)
export interface Item { id: number; name: string; description: string; }; export interface AppStore { items: Item[]; selectedItem: Item;};
Code Sample
![Page 87: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/87.jpg)
Error HandlingWe should always handle errors Chain the .catch method on an observable Pass in a callback with a single error argument
this.http.get('users.json') .catch(error => { console.error(error); return Observable.throw(error.json().error || 'Server error'); });
![Page 88: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/88.jpg)
getItems() { return this._http.get('fileDoesNotExist.json') .map(result => result.json()) .catch(this.handleError);} private handleError (error: Response) { console.error(error); return Observable.throw(error.json().error || 'Server error');}
Observable.catch
![Page 89: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/89.jpg)
HeadersImport Headers and RequestOptions: import {Headers, RequestOptions} from 'angular2/http';
Headers are an instance of the Headers class Pass in an object with each header as a key-value pair Then pass this Headers instance into a new RequestOptions instance
let headers = new Headers({ 'Content-Type': 'application/json' }); let options = new RequestOptions({ headers: headers }); this.http.post('users.json', '{}', options);
![Page 90: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/90.jpg)
Demonstration
![Page 91: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/91.jpg)
Challenges• Create a method inside the service that uses HTTP to
get widgets.json • Return that method from the service and subscribe to it
in the component so you can display the data inside the component’s template
• Change the method to use promises and update the component accordingly
• BONUS create another method that POSTs to widgets.json
![Page 92: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/92.jpg)
Pipes
![Page 93: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/93.jpg)
Pipes• What are Pipes? • Built-in Pipes • Custom Pipes • Async Pipes
![Page 94: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/94.jpg)
What are Pipes?A pipe takes in data as input and transforms it to a desired output
We use them in our templates with interpolation: <p>User created on {{ created_at | date }}</p>
Include parameters to a pipe by separating them with a colon: <p>User created on {{ created_at | date:"MM/dd/yy" }}</p>
Pipes are chain-able: <p>User created on {{ created_at | date | uppercase }}</p>
![Page 95: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/95.jpg)
Built-in PipesDatePipe <p>User created on {{ user.created_at | date }}</p> UpperCasePipe <p>Middle Initial: {{ user.middle | uppercase }}</p> LowerCasePipe <p>Username: {{ user.username | lowercase }}</p> CurrencyPipe <p>Price Plan: {{ user.plan.price | currency }}</p> PercentPipe <p>Data Usage: {{ user.usage | percent }}</p>
![Page 96: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/96.jpg)
Custom PipesImport the pipe decorator and PipeTransform interface: import { Pipe, PipeTransform } from 'angular2/core';
Create a class that implements the PipeTransform interface and includes a transform method: export class ReversePipe implements PipeTransform { transform(value:string, args:string[]) : any { return value.reverse(); } }
![Page 97: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/97.jpg)
Async PipeResolves async data (observables/promises) directly in the template
Skips the process of having to manually subscribe to async methods in the component and then setting those values for the template to bind to
Component attribute: asyncAttribute<string> = new Promise((resolve, reject) => { setTimeout(() => resolve('Promise resolved'), 500); })
Template: <p>Async result: {{asyncAttribute | async}}</p>
![Page 98: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/98.jpg)
Demonstration
![Page 99: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/99.jpg)
Challenges• Use two or more built-in pipes to transform data in the
template • Create a custom pipe that filters an array of strings
based on a particular letter • Create an asynchronous method or attribute on the
component and bind to it in the template
![Page 100: Build Better Apps with Angular 2 - Day - Frontend · PDF file•Denotes an optional value for a particular route ... Component Composition ... subscribed to while promises run no matter](https://reader031.vdocument.in/reader031/viewer/2022030500/5aacbe1a7f8b9a2e088d5b56/html5/thumbnails/100.jpg)
Thanks!