1.5 Our First Component
System.import('app/main').catch(function(err){ console.error(err); });
</script>
</head>
index.html
Typings are used by your editor to give you code hinting/intellisense, and es6-shim.min.js is a code that emulates ES6 features for ES5 browsers
A Zone is an execution context that persists across async tasks. You can think of it as thread-local storage for JavaScript VMs
A number of use cases (Composition/Dependency Injection, Runtime Type Assertions,Reflection/Mirroring, Testing) want the ability to add additional metadata to a class in a consistent manner. A consistent approach is needed for various tools and libraries to be able to reason overmetadata.
Web Application for Text and Source Code compare. Code Compare is a sample application designed to compare and visualising different texts and sources.
import { NgModule, Component , Injectable }} from '@angular/core';import { FormsModule } from '@angular/forms';import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
@NgModule
@NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] })
@NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent ], providers: [ RaceService ], bootstrap: [ AppComponent ] })
@NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent,RacesComponent ], bootstrap: [ AppComponent ] })
@Component
@Component({ selector:'racing-app', template:`{{heading}} })
@Component({ selector: 'my-races', templateUrl: 'app/races.component.html', styleUrls:['app/races.component.css'] })
platformBrowserDynamic() .bootstrapModule(AppModule);
<html> <head> <title>Racing App</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="styles.css"> <script src="https://unpkg.com/core-js/client/shim.min.js"></script> <script src="https://unpkg.com/zone.js@0.6.25?main=browser"></script> <script src="https://unpkg.com/reflect-metadata@0.1.8"></script> <script src="https://unpkg.com/systemjs@0.19.39/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('app/main').catch(function(err){ console.error(err); }); </script> </head> <body> <racing-app> <h1>Loading...</h1></racing-app> </body> </html>
app/main.ts
import { NgModule, Component } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; @Component({ selector:'racing-app', template:`{{heading}} }) class AppComponent { heading = "Ultra Racing Schedule" } @NgModule({ imports: [ BrowserModule ], declarations: [AppComponent], bootstrap:[AppComponent] }) class AppModule {} platformBrowserDynamic() .bootstrapModule(AppModule);
______________________________________________________________________________
1.6 Making It Dynamic
app/main.ts
import { NgModule, Component } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; @Component({ selector: 'racing-app', template: `{{ heading }}
{{race.name}}
{{race.date}} {{race.about}} ` }) class AppComponent { heading = "Ultra Racing Schedule" race = { "id": 1, "name": "Daytona Thunderdome", "date": new Date('2512-01-04T14:00:00'), "about": "Race through the ruins of an ancient Florida battle arena.", "entryFee": 3200 } } @NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) class AppModule {} platformBrowserDynamic() .bootstrapModule(AppModule);
______________________________________________________________________________
2.4 Looping
2.5 Conditionals
______________________________________________________________________________
2.9 Methods
At the bottom of our template we've added a place to display our total cost. Our total cost will be calculated by summing up theentryFee
properties of ONLY the races we are racing in ( isRacing
istrue
). Write a method named totalCost()
in our AppComponent
that returns this value.app/main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import { NgModule, Component } from '@angular/core'; @Component({ selector: 'racing-app', template: `{{heading}}
{{race.name}} {{race.entryFee | currency:'USD':true}}
{{race.date | date:'MMM d, y, h:MM a'}} {{race.about}}Already Racing
Total cost: {{totalCost() | currency:'USD':true}}
` }) export class AppComponent { heading = "Ultra Racing Schedule" cash = 10000; races = [{ "id": 1, "name": "Daytona Thunderdome", "date": new Date('2512-01-04T14:00:00'), "about": "Race through the ruins of an ancient Florida battle arena.", "entryFee": 3200, "isRacing": false }, { "id": 2,"name": "San Francisco Ruins", "date": new Date('2512-07-03T20:00:00'), "about": "Drift down the streets of a city almost sunk under the ocean.", "entryFee": 4700, "isRacing": true }, { "id": 3,"name": "New York City Skyline", "date": new Date('2512-07-12T21:00:00'), "about": "Fly between buildings in the electronic sky.", "entryFee": 4300, "isRacing": true }]; totalCost() { let sum = 0; for (let race of this.races){ if(race.isRacing) { sum += race.entryFee; } } return sum; } } @NgModule({imports: [ BrowserModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) class AppModule {} platformBrowserDynamic().bootstrapModule(AppModule);______________________________________________________________________________
3.3 Refactoring Classes
Both ourapp.component.ts
and our races.component.ts
are missing the export
keyword to allow their classes to be imported. Could you add them where they’re needed?app/app.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'racing-app', template: {{heading} my-races
` }) export class AppComponent { heading = "Ultra Racing Schedule" }
app/races.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'my-races', template: `Cash left to enter races: {{cashLeft() | currency:'USD':true}}
{{race.name}} {{race.entryFee | currency:'USD':true}}
{{race.date | date:'MMM d, y, h:MM a'}} {{race.about}}Already Racing
Total cost: {{totalCost() | currency:'USD':true}}
` }) export class RacesComponent { heading = "Ultra Racing Schedule" cash = 10000; races = [{"id": 1, "name": "Daytona Thunderdome", "date": new Date('2512-01-04T14:00:00'), "about": "Race through the ruins of an ancient Florida battle arena.", "entryFee": 3200, "isRacing": false }, { "id": 2,"name": "San Francisco Ruins", "date": new Date('2512-07-03T20:00:00'), "about": "Drift down the streets of a city almost sunk under the ocean.", "entryFee": 4700, "isRacing": true }, { "id": 3,"name": "New York City Skyline", "date": new Date('2512-07-12T21:00:00'), "about": "Fly between buildings in the electronic sky.", "entryFee": 4300, "isRacing": true }]; totalCost() { let sum = 0; for (let race of this.races) { if (race.isRacing) sum += race.entryFee; } return sum; } cashLeft() { return this.cash - this.totalCost(); } }app/main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { RacesComponent } from './races.component'; @NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent,RacesComponent ], bootstrap: [ AppComponent ] }) class AppModule {} platformBrowserDynamic().bootstrapModule(AppModule);
______________________________________________________________________________
3.5 Adding HTML and CSS
app/races.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'my-races', templateUrl:'app/races.component.html', styleUrls['app/races.component.css']; }) export class RacesComponent { heading = "Ultra Racing Schedule" cash = 10000; races = [{ "id": 1, "name": "Daytona Thunderdome", "date": new Date('2512-01-04T14:00:00'), "about": "Race through the ruins of an ancient Florida battle arena.", "entryFee": 3200, "isRacing": false }, { "id": 2, "name": "San Francisco Ruins", "date": new Date('2512-07-03T20:00:00'), "about": "Drift down the streets of a city almost sunk under the ocean.", "entryFee": 4700, "isRacing": true }, { "id": 3, "name": "New York City Skyline", "date": new Date('2512-07-12T21:00:00'), "about": "Fly between buildings in the electronic sky.", "entryFee": 4300, "isRacing": true }]; totalCost() { let sum = 0; for (let race of this.races) { if (race.isRacing) sum += race.entryFee; } return sum; } cashLeft() { return this.cash - this.totalCost(); } }
______________________________________________________________________________
DATA ORGANIZATION
3.8 Modeling and Mocking
app/race.ts
export class Race { id: number; name: string; date: Date; about: string; entryFee: number; isRacing: boolean; }
How to declare mock data ?
app/mocks.ts
import { Race } from './race'; export const RACES: races[]=[{ "id": 1, "name": "Daytona Thunderdome", "date": new Date('2512-01-04T14:00:00'), "about": "Race through the ruins of an ancient Florida battle arena.", "entryFee": 3200, "isRacing": false }, { "id": 2, "name": "San Francisco Ruins", "date": new Date('2512-07-03T20:00:00'), "about": "Drift down the streets of a city almost sunk under the ocean.", "entryFee": 4700, "isRacing": true }, { "id": 3, "name": "New York City Skyline", "date": new Date('2512-07-12T21:00:00'), "about": "Fly between buildings in the electronic sky.", "entryFee": 4300, "isRacing": true }];
app/races.component.ts
import { Component } from '@angular/core'; import { Race } from './race'; import { RACES } from './mocks'; @Component({ selector: 'my-races', templateUrl: 'app/races.component.html', styleUrls:['app/races.component.css'] }) export class RacesComponent { heading = "Ultra Racing Schedule" cash = 10000; races: Race[]; ngOnInit(){ this.races = RACES; } totalCost() { let sum = 0; for (let race of this.races) { if (race.isRacing) sum += race.entryFee; } return sum; } cashLeft() { return this.cash - this.totalCost(); } }
______________________________________________________________________________
DATA BINDING BOOST
4.1 Property & Class Binding
We've gone ahead and applied new HTML and CSS to our app to make it prettier. We also have two new fields in our model and mocks:
image
and imageDescription
.app/races.component.html
<main class="container" role="main"> <h2>Cash left to enter races: <span>{{cashLeft() | currency:'USD':true}}</span> </h2> <ul> <li class="card" *ngFor="let race of races" [class.racing]="race.isRacing" > <div class="panel-body"> <div class="photo"> <img [alt]="race.imageDescription" [src]= "race.image" > </div> <table class="race-info"> <tr> <td> <h3>{{race.name}}</h3> <p class="date">{{race.date | date:'MMM d, y, h:MM a'}}</p> <p class="description">{{race.about}}</p> </td> <td> <p class="price">{{race.entryFee | currency:'USD':true}}</p> </td> <td> <button class="button" *ngIf="!race.isRacing">Enter Race</button> <div *ngIf="race.isRacing"> <p class="status">Racing</p> <button class="button-cancel">Cancel Race</button> </div> </td> </tr> </table> </div> </li> </ul> <div class="price-total"> <h3>Total cost:</h3> <p>{{totalCost() | currency:'USD':true}}</p> </div> </main>
______________________________________________________________________________
Time to implement the "Enter Race" button and "Cancel Race" link.
app/races.component.html
<main class="container" role="main"> <h2>Cash left to enter races: <span>{{cashLeft() | currency:'USD':true}}</span> </h2> <ul> <li class="card" *ngFor="let race of races" [class.racing]="race.isRacing" > <div class="panel-body"> <div class="photo"> <img [src]="race.image" [alt]="race.imageDescription"> </div> <table class="race-info"> <tr> <td> <h3>{{race.name}}</h3> <p class="date">{{race.date | date:'MMM d, y, h:MM a'}}</p> <p class="description">{{race.about}}</p> </td> <td> <p class="price">{{race.entryFee | currency:'USD':true}}</p> </td> <td> <button class="button" *ngIf="!race.isRacing" (click)="enterRace(race)" >Enter Race</button> <div *ngIf="race.isRacing"> <p class="status">Racing</p> <button class="button-cancel" (click)="cancelRace(race)" >Cancel Race</button> </div> </td> </tr> </table> </div> </li> </ul> <div class="price-total"> <h3>Total cost:</h3> <p>{{totalCost() | currency:'USD':true}}</p> </div> </main>
app/races.component.ts
import { Component } from '@angular/core'; import { Race } from './race'; import { RACES } from './mocks'; @Component({ selector: 'my-races', templateUrl: 'app/races.component.html', styleUrls:['app/races.component.css'] }) export class RacesComponent { heading = "Ultra Racing Schedule" cash = 10000; races: Race[]; ngOnInit() { this.races = RACES; } totalCost() { let sum = 0; for (let race of this.races) { if (race.isRacing) sum += race.entryFee; } return sum; } cashLeft() { return this.cash - this.totalCost(); } cancelRace(race){ race.isRacing = false; } enterRace(race){ if(this.cashLeft()>race.entryFee){ race.isRacing = true; }else{ race.isRacing = false; alert( "You don't have enough cash"); } } }
______________________________________________________________________________
Sending Event Data
4.8 Input Binding
app/races.component.html
<main class="container" role="main"> <h2>Money for racing: <input type="text" class="cash" [(ngModel)]="cash"></h2> <h2>Cash left to enter races: <span>{{cashLeft() | currency:'USD':true}}</span> </h2> <ul> <li class="card" *ngFor="let race of races" [class.racing]="race.isRacing" > <div class="panel-body"> <div class="photo"> <img [src]="race.image" [alt]="race.imageDescription"> </div> <table class="race-info"> <tr> <td> <h3>{{race.name}}</h3> <p class="date">{{race.date | date:'MMM d, y, h:MM a'}}</p> <p class="description">{{race.about}}</p> </td> <td> <p class="price">{{race.entryFee | currency:'USD':true}}</p> </td> <td> <button class="button" *ngIf="!race.isRacing" (click)="enterRace(race)">Enter Race</button> <div *ngIf="race.isRacing"> <p class="status">Racing</p> <button class="button-cancel" (click)="cancelRace(race)">Cancel Race</button> </div> </td> </tr> </table> </div> </li> </ul> <div class="price-total"> <h3>Total cost:</h3> <p>{{totalCost() | currency:'USD':true}}</p> </div> </main>
This symbol
[()]
is sometimes called?banana in a box
______________________________________________________________________________
5.3 Moving to a Service 175 PTS
It's time to move our mocks into services for our racing schedule app. We've gone ahead and started creating a
race.service.ts
file for you. Please note that this is a RaceService
class, not RacingDataService
class like in the slides. We need your help hooking it all up.app/race.service.ts
import { RACES } from './mocks'; import { Injectable } from '@angular/core'; @Injectable() export class RaceService { getRaces() { return RACES; } }
app/main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { RacesComponent } from './races.component'; import { RaceService } from './race.service'; @NgModule({ imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent ], providers: [ RaceService ], bootstrap: [ AppComponent ] }) class AppModule {} platformBrowserDynamic().bootstrapModule(AppModule);
app/races.component.ts
import { Component } from '@angular/core'; import { Race } from './race'; import { RaceService } from './race.service'; @Component({ selector: 'my-races', templateUrl: 'app/races.component.html', styleUrls:['app/races.component.css'] }) export class RacesComponent { heading = "Ultra Racing Schedule" cash = 10000; races: Race[]; constructor(private raceService: RaceService) { } ngOnInit() { this.races = this.raceService.getRaces(); } totalCost() { let sum = 0; for (let race of this.races) { if (race.isRacing) sum += race.entryFee; } return sum; } cashLeft() { return this.cash - this.totalCost(); } enterRace(race) { if (this.cashLeft() > race.entryFee) { race.isRacing = true; } else { alert("You don't have enough cash"); } } cancelRace(race) { race.isRacing = false; } }
______________________________________________________________________________
5.5 Over the Internet 250 PTS
We've gone ahead and created a
races.json
file for you — check it out. Let's import and usehttp
to fetch our data.______________________________________________________________________________
System.import('app').catch(function(err){console.error(err);})
No comments:
Post a Comment