1 @Component({ 2 selector: 'app-heroes', 3 templateUrl: './heroes.component.html', 4 styleUrls: ['./heroes.component.css'] 5 })
在使用表單輸入綁定數據以前,咱們須要引入表單模塊FormsModule
包至咱們的Angular模塊中。引入包的方法是,直接添加須要的包至NgModel
的imports
數組中。javascript
1 import { BrowserModule } from '@angular/platform-browser'; 2 import { NgModule } from '@angular/core'; 3 import { FormsModule } from '@angular/forms'; 4 5 import { AppComponent } from './app.component'; 6 import { HeroesComponent } from './heroes/heroes.component'; 7 8 9 @NgModule({ 10 declarations: [ 11 AppComponent, 12 HeroesComponent 13 ], 14 imports: [ 15 BrowserModule, 16 FormsModule 17 ], 18 providers: [], 19 bootstrap: [AppComponent] 20 }) 21 export class AppModule { }
表單中寫法:css
1 <input [(ngModel)]="hero.name" placeholder="name">
1 const HEROES: Hero[] = [ 2 {id: 11, name: 'Mr.Nice'}, 3 {id: 12, name: 'Narco'}, 4 {id: 13, name: 'Bombasto'}, 5 {id: 14, name: 'Celeritas'}, 6 {id: 15, name: 'Magneta'}, 7 {id: 16, name: 'RubberMan'}, 8 {id: 17, name: 'Dynama'}, 9 {id: 18, name: 'Dr IQ'}, 10 {id: 19, name: 'Magma'}, 11 {id: 20, name: 'Tornado'} 12 ];
li
1 <li *ngFor="let hero of heroes"> 2 <span class="badge">{{hero.id}}</span> 3 {{hero.name}} 4 </li>
1 @Component({ 2 selector: 'my-app', 3 template: ``, 4 styles: [` 5 .selected { 6 background-color: #CFD8DC; 7 color:white; 8 } 9 .heroes { 10 margin: 0 0 2em 0; 11 list-style-type: none; 12 padding: 0; 13 width: 15em; 14 } 15 `] 16 }]
與Java/C++定義變量的類型寫在前面不一樣的時,TypeScript的定義方式爲html
變量名:類型
java
1 selectedHero:Hero;
必須定義返回類型web
1 onSelect(hero: Hero): void { 2 this.selectedHero = hero; 3 }
直接使用某個可能爲空的變量,會致使異常拋出,須要使用if
結構進行判斷。angular中有一種名爲結構指令(structural directives)
能夠改變DOM的結構。這類的指令有ngIf
和ngFor
。用法以下:數據庫
1 <div *ngIf="selectedHero"> 2 <h2>{{selectedHero.name}} details!</h2> 3 <div><label>id:</label>{{selectedHero.id}}</div> 4 <div><label>name:</label>{{selectedHero.name}}</div> 5 </div>
[class.className]=true/falsejson
key爲樣式的類名,value爲true或者false.應用:已選擇的項添加已選擇
樣式。未選擇的項消除已選擇
樣式bootstrap
1 <li *ngFor="let hero of heroes" (click)="onSelect(hero)" [class.selected]="hero === selectedHero"> 2 <span class="badge">{{hero.id}}</span> 3 {{hero.name}} 4 </li>
1 import { Hero } from './hero';
使用@Injectable
修飾類api
import {Injectable} from '@angular/core'; import {HEROES} from "./mock-heroes"; import {Hero} from "./hero"; @Injectable() export class HeroServie { getHeroes(): Hero[] { return HEROES } }
如何在組件中使用這個服務?傳統的方式會使用new
關鍵字去實例化。但官方不建議這麼作,有如下幾點理由:數組
當服務類的構造方法改變時,咱們必需要修改每一處使用到它的代碼
若是須要緩存對象的狀態,每次都new是作不到的。
在代碼中寫死new類來實例化,將沒法替換其實現。好比,測試環境和生產環境的服務可能不一樣,當要切換不一樣版本是比較麻煩的。
官方推薦使用注入
來使用服務。爲組件添加providers
元數據。
1 providers: [HeroServie],
組件的構造方法改成:
1 constructor(private heroService: HeroServie) { 2 this.heroes = heroService.getHeroes(); 3 }
ngOnInit
生命週期回調接口angular提供了一系統的接口監控組件的生命週期各個環節。
1 import { OnInit } from '@angular/core'; 2 3 export class AppComponent implements OnInit { 4 5 ngOnInit(): void { 6 7 // somthing to be done 8 9 } 10 11 }
Promise
解決回調的問題服務有時候是耗時的操做,若是直接調用可能會阻塞UI,使用Promise能夠解決這個問題。
1 @Injectable() 2 export class HeroServie { 3 getHeroes(): Promise<Hero[]> { 4 return Promise.resolve(HEROES); 5 } 6 7 }
1 private getHeroes() : void { 2 this.heroService.getHeroes().then(heroes => this.heroes = heroes); 3 }
路由配置文件寫法
import {Routes, RouterModule} from "@angular/router"; import {ModuleWithProviders} from "@angular/core"; import {HeroesComponent} from "./heroes.component"; const appRoutes: Routes = [{ path: 'heroes', component: HeroesComponent }]; export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
模板中使用
1 <a routerLink="/heroes">Heroes</a> 2 <router-outlet></router-outlet>
routerLink指令告知路由器點擊跳轉至哪一個地址,<router-outlet></router-outlet>
表示路由出口,即要把組件(routerLink指向的組件)
加載在哪一個位置.
1 @Component({ 2 selector: 'my-dashboard', 3 templateUrl: 'app/dashboard.component.html' 4 })
1 this.heroService.getHeroes().then(heroes=>this.heroes = heroes.slice(1, 5));
路由配置:id爲參數
1 { 2 path: 'detail/:id', 3 component: HeroDetailComponent 4 }
獲取參數:
1 export class HeroDetailComponent implements OnInit { 2 ngOnInit(): void { 3 this.route.params.forEach((params: Params)=> { 4 let id = +params['id']; //加號的做用是將字符串參數轉化爲數字 5 this.heroService.getHero(id).then(hero => this.hero = hero); 6 }); 7 } 8 9 constructor(private heroService: HeroServie, 10 private route: ActivatedRoute) { 11 12 } 13 14 @Input() 15 hero: Hero; 16 17 }
1 gotoDetail(hero: Hero): void { 2 let link = ['/detail', hero.id]; 3 this.router.navigator(link); 4 }
內存數據模擬數據庫數據。
1 InMemoryWebApiModule.forRoot(InMemoryDataService),
service實現
1 import {InMemoryDbService} from "angular2-in-memory-web-api"; 2 3 export class InMemoryDataService implements InMemoryDbService { 4 createDb(): {} { 5 let heroes = [ 6 {id: 11, name: 'Mr. Nice'}, 7 {id: 12, name: 'Narco'}, 8 {id: 13, name: 'Bombasto'}, 9 {id: 14, name: 'Celeritas'}, 10 {id: 15, name: 'Magneta'}, 11 {id: 16, name: 'RubberMan'}, 12 {id: 17, name: 'Dynama'}, 13 {id: 18, name: 'Dr IQ'}, 14 {id: 19, name: 'Magma'}, 15 {id: 20, name: 'Tornado'} 16 ] 17 return heroes; 18 } 19 20 }
HTTP請求示例
1 getHeroes(): Promise<Hero[]> { 2 return this.http 3 .get(this.heroesUrl) 4 .toPromise() 5 .then(response => response.json().data as Hero[]) // 轉換類型 6 .catch(this.handleError) 7 }
Angular的http.get
返回的是Observable
,Observables是一個強大的管理異步數據流的方式。
當咱們使用toPromise
方法將Observables轉化爲Promise後,操做就像操做普通的Promise同樣。使用toPromise方法須要引入外部方法
1 import 'rxjs/add/operator/toPromise';
1 .catch(this.handleError);
1 private handleError(error: any): Promise<any> { 2 3 console.error('An error occurred', error); // for demo purposes only 4 5 return Promise.reject(error.message || error); 6 7 }
angular體系主要包括:模塊Module,組件Component,模板Template,元數據Metadata,數據綁定Data Banding,服務Service,指令,依賴注入
模塊是ES6標準之一,每一個模塊目的性很是單一。在Angular中,通常模塊輸出的都是一個組件類,須要配合import
來加載模塊。
有一類模塊是Angular自己定義好的,即庫模塊,當加載angular2/core
模塊時,能夠調用一個核心類庫。庫模塊入要有angular/core(核心類庫)
,angular/http(網絡請求相關)
,angular2/router(路由相關)
,angular2/common(表單、指令等)
1 總結 - Angular應用由模塊組成 2 3 - 模塊輸出能夠是:類、函數、值或其餘模塊
組件是爲了控制顯示把HTML模板及樣式。通常,每一個組件都配有一個類,用來定義業務能力。經過類的屬性和方法與視圖進行交互。
模板是爲了告知Angular如何去渲染組件。Angular模板有其特殊的語法。
元數據是告知Angular如何處理一個類。一個類若是沒有元數據的聲明,就是一個沒法單獨運行的普通的類。可使用註解
來定義類的元數據。如@Component
,註解中能夠帶上一些參數:
1 - selector - CSS選擇器 2 3 - templateUrl - 的模板地址 4 5 - directives - 指令或組件數組 6 7 - providers - 註冊的Service服務數組,從而在組件類構造函數中可以正確的實例化這些服務
除了@Component
外,還有Injectable
,@Input
,@Output
,@RouterConfig
元數據。
數據綁定是一種協調組件與模板之間的通訊機制,經過HTML元素來描述採用哪一種數據綁定形式。數據綁定包括屬性綁定[hero]
、事件綁定(click)
、雙向綁定[(ngModel)]="hero.name"
指令。一個指令是由元數據和一個類組成,使用元數據註解@Directive
修飾就是一個指令。指令和組件的功能相似,他們的區別是指令側重對HTML元素功能的擴展。而組件是一個具體一的業務。指令分爲結構性指令如*ngFor
,*ngIf
等和屬性指令,如[(ngModel)]
服務。模塊中須要使用到的值、函數均可以是服務Service。服務一般 是一個目的性很是明確的類。如日誌Service,數據Service,應用程序配置信息,工資計算器等 。
組件是是服務的最大消費者,組件都是靠服務來處理大部分事務,組件不會直接從服務器獲取數據、不驗證用戶輸入,都是委派驗服務來完成。通常咱們遵循的原則是:把應用程序邏輯轉化成服務 ,並經過依賴注入提供組件來消費服務。
依賴注入。依賴注入是一種對類實例的新方法。咱們能夠在引導應用程序啓動時實例一個服務如
1 bootstrap(AppComponent, [BackendService, HeroService, Logger]);
或者在組件級別裏註冊服務
1 @Component({ 2 providers: [HeroService] 3 }) 4 export class HeroesComponent { ... }
@Component({
selector: 'my-app',
template: `<h1>{{title}}</h1> <h2>{{hero.name}} details!</h2>
<div><label>id:</label>{{hero.id}}</div> <div><label>name:</label>{{hero.name}}</div>` })
在使用表單輸入綁定數據以前,咱們須要引入表單模塊FormsModule
包至咱們的Angular模塊中。引入包的方法是,直接添加須要的包至NgModel
的imports
數組中。
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {AppComponent} from './app.component';
import {FormsModule} from "@angular/forms";
@NgModule({
imports: [
BrowserModule,
FormsModule
],
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule {
}
表單中寫法:
<input [(ngModel)]="hero.name" placeholder="name">
const HEROES: Hero[] = [
{id: 11, name: 'Mr.Nice'},
{id: 12, name: 'Narco'},
{id: 13, name: 'Bombasto'},
{id: 14, name: 'Celeritas'},
{id: 15, name: 'Magneta'},
{id: 16, name: 'RubberMan'},
{id: 17, name: 'Dynama'},
{id: 18, name: 'Dr IQ'},
{id: 19, name: 'Magma'},
{id: 20, name: 'Tornado'}
];
li
<li *ngFor="let hero of heroes">
<span class="badge">{{hero.id}}</span>
{{hero.name}}
</li>
@Component({ selector: 'my-app', template: ``, styles: [` .selected {
background-color: #CFD8DC;
color:white;
}
.heroes { margin: 0 0 2em 0; list-style-type: none; padding: 0; width: 15em; }
`]
}]
與Java/C++定義變量的類型寫在前面不一樣的時,TypeScript的定義方式爲
變量名:類型
selectedHero:Hero;
必須定義返回類型
onSelect(hero: Hero): void {
this.selectedHero = hero;
}
直接使用某個可能爲空的變量,會致使異常拋出,須要使用if
結構進行判斷。angular中有一種名爲結構指令(structural directives)
能夠改變DOM的結構。這類的指令有ngIf
和ngFor
。用法以下:
<div *ngIf="selectedHero">
<h2>{{selectedHero.name}} details!</h2>
<div><label>id:</label>{{selectedHero.id}}</div>
<div><label>name:</label>{{selectedHero.name}}</div>
</div>
[class.className]=true/false
key爲樣式的類名,value爲true或者false.應用:已選擇的項添加已選擇
樣式。未選擇的項消除已選擇
樣式。
<li *ngFor="let hero of heroes" (click)="onSelect(hero)" [class.selected]="hero === selectedHero">
<span class="badge">{{hero.id}}</span>
{{hero.name}}
</li>
import { Hero } from './hero';
使用@Injectable
修飾類
import {Injectable} from '@angular/core';
import {HEROES} from "./mock-heroes";
import {Hero} from "./hero";
@Injectable()
export class HeroServie {
getHeroes(): Hero[] {
return HEROES
}
}
如何在組件中使用這個服務?傳統的方式會使用new
關鍵字去實例化。但官方不建議這麼作,有如下幾點理由:
當服務類的構造方法改變時,咱們必需要修改每一處使用到它的代碼
若是須要緩存對象的狀態,每次都new是作不到的。
在代碼中寫死new類來實例化,將沒法替換其實現。好比,測試環境和生產環境的服務可能不一樣,當要切換不一樣版本是比較麻煩的。
官方推薦使用注入
來使用服務。爲組件添加providers
元數據。
providers: [HeroServie],
組件的構造方法改成:
constructor(private heroService: HeroServie) {
this.heroes = heroService.getHeroes();
}
ngOnInit
生命週期回調接口angular提供了一系統的接口監控組件的生命週期各個環節。
import { OnInit } from '@angular/core';
export class AppComponent implements OnInit {
ngOnInit(): void {
// somthing to be done
}
}
Promise
解決回調的問題服務有時候是耗時的操做,若是直接調用可能會阻塞UI,使用Promise能夠解決這個問題。
@Injectable()
export class HeroServie {
getHeroes(): Promise<Hero[]> {
return Promise.resolve(HEROES);
}
}
private getHeroes() : void {
this.heroService.getHeroes().then(heroes => this.heroes = heroes);
}
路由配置文件寫法
import {Routes, RouterModule} from "@angular/router";
import {ModuleWithProviders} from "@angular/core";
import {HeroesComponent} from "./heroes.component";
const appRoutes: Routes = [{
path: 'heroes',
component: HeroesComponent
}];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
模板中使用
<a routerLink="/heroes">Heroes</a>
<router-outlet></router-outlet>
routerLink指令告知路由器點擊跳轉至哪一個地址,<router-outlet></router-outlet>
表示路由出口,即要把組件(routerLink指向的組件)
加載在哪一個位置.
@Component({
selector: 'my-dashboard',
templateUrl: 'app/dashboard.component.html'
})
this.heroService.getHeroes().then(heroes=>this.heroes = heroes.slice(1, 5));
路由配置:id爲參數
{
path: 'detail/:id',
component: HeroDetailComponent
}
獲取參數:
export class HeroDetailComponent implements OnInit {
ngOnInit(): void {
this.route.params.forEach((params: Params)=> {
let id = +params['id']; //加號的做用是將字符串參數轉化爲數字
this.heroService.getHero(id).then(hero => this.hero = hero);
});
}
constructor(private heroService: HeroServie,
private route: ActivatedRoute) {
}
@Input()
hero: Hero;
}
gotoDetail(hero: Hero): void {
let link = ['/detail', hero.id];
this.router.navigator(link);
}
內存數據模擬數據庫數據。
InMemoryWebApiModule.forRoot(InMemoryDataService),
service實現
import {InMemoryDbService} from "angular2-in-memory-web-api";
export class InMemoryDataService implements InMemoryDbService {
createDb(): {} {
let heroes = [
{id: 11, name: 'Mr. Nice'},
{id: 12, name: 'Narco'},
{id: 13, name: 'Bombasto'},
{id: 14, name: 'Celeritas'},
{id: 15, name: 'Magneta'},
{id: 16, name: 'RubberMan'},
{id: 17, name: 'Dynama'},
{id: 18, name: 'Dr IQ'},
{id: 19, name: 'Magma'},
{id: 20, name: 'Tornado'}
]
return heroes;
}
}
HTTP請求示例
getHeroes(): Promise<Hero[]> {
return this.http
.get(this.heroesUrl)
.toPromise()
.then(response => response.json().data as Hero[]) // 轉換類型
.catch(this.handleError)
}
Angular的http.get
返回的是Observable
,Observables是一個強大的管理異步數據流的方式。
當咱們使用toPromise
方法將Observables轉化爲Promise後,操做就像操做普通的Promise同樣。使用toPromise方法須要引入外部方法。
import 'rxjs/add/operator/toPromise';
.catch(this.handleError);
private handleError(error: any): Promise<any> {
console.error('An error occurred', error); // for demo purposes only
return Promise.reject(error.message || error);
}
angular體系主要包括:模塊Module,組件Component,模板Template,元數據Metadata,數據綁定Data Banding,服務Service,指令,依賴注入
模塊是ES6標準之一,每一個模塊目的性很是單一。在Angular中,通常模塊輸出的都是一個組件類,須要配合import
來加載模塊。
有一類模塊是Angular自己定義好的,即庫模塊,當加載angular2/core
模塊時,能夠調用一個核心類庫。庫模塊入要有angular/core(核心類庫)
,angular/http(網絡請求相關)
,angular2/router(路由相關)
,angular2/common(表單、指令等)
- Angular應用由模塊組成
- 模塊輸出能夠是:類、函數、值或其餘模塊
組件是爲了控制顯示把HTML模板及樣式。通常,每一個組件都配有一個類,用來定義業務能力。經過類的屬性和方法與視圖進行交互。
模板是爲了告知Angular如何去渲染組件。Angular模板有其特殊的語法。
元數據是告知Angular如何處理一個類。一個類若是沒有元數據的聲明,就是一個沒法單獨運行的普通的類。可使用註解
來定義類的元數據。如@Component
,註解中能夠帶上一些參數:
- selector - CSS選擇器
- templateUrl - 的模板地址
- directives - 指令或組件數組
- providers - 註冊的Service服務數組,從而在組件類構造函數中可以正確的實例化這些服務
除了@Component
外,還有Injectable
,@Input
,@Output
,@RouterConfig
元數據。
數據綁定是一種協調組件與模板之間的通訊機制,經過HTML元素來描述採用哪一種數據綁定形式。數據綁定包括屬性綁定[hero]
、事件綁定(click)
、雙向綁定[(ngModel)]="hero.name"
指令。一個指令是由元數據和一個類組成,使用元數據註解@Directive
修飾就是一個指令。指令和組件的功能相似,他們的區別是指令側重對HTML元素功能的擴展。而組件是一個具體一的業務。指令分爲結構性指令如*ngFor
,*ngIf
等和屬性指令,如[(ngModel)]
服務。模塊中須要使用到的值、函數均可以是服務Service。服務一般 是一個目的性很是明確的類。如日誌Service,數據Service,應用程序配置信息,工資計算器等 。
組件是是服務的最大消費者,組件都是靠服務來處理大部分事務,組件不會直接從服務器獲取數據、不驗證用戶輸入,都是委派驗服務來完成。通常咱們遵循的原則是:把應用程序邏輯轉化成服務 ,並經過依賴注入提供組件來消費服務。
依賴注入。依賴注入是一種對類實例的新方法。咱們能夠在引導應用程序啓動時實例一個服務如
bootstrap(AppComponent, [BackendService, HeroService, Logger]);
或者在組件級別裏註冊服務
@Component({
providers: [HeroService]
})
export class HeroesComponent { ... }