摘要:首先,我們需要在入口頁(yè)面的中配置根路徑然后創(chuàng)建一個(gè)路由模塊路由配置在主模塊中導(dǎo)入配置好的路由模塊而在頁(yè)面中需要一個(gè)容器去承載上面代碼中的定義了用戶點(diǎn)擊后的路由跳轉(zhuǎn),定義該路由激活時(shí)的樣式類。
剛實(shí)習(xí)的時(shí)候用過(guò)AngularJS,那時(shí)候真的是連原生JavaScript都不會(huì)寫,依樣畫葫蘆做了幾個(gè)管理后臺(tái)。然后突然換項(xiàng)目了,AngularJS就不寫了,感覺(jué)前前后后接觸了一年多的AngularJS,結(jié)果只懂點(diǎn)皮毛。
最近又有個(gè)管理后臺(tái)的需求,決定再拾起,但現(xiàn)在是升級(jí)版的Angular了。終于,有機(jī)會(huì)好好再看一眼Angular了,這次希望能深入一點(diǎn)了解。
本文是筆者在學(xué)習(xí)開發(fā)過(guò)程中的總結(jié)輸出,目的在于讓初次接觸Angular的開發(fā)者對(duì)該框架能有整體的認(rèn)識(shí),并且能快速上手開發(fā)工作。
AngularJS VS AngularAngularJS最大版本號(hào)只有1.x,2.x/4.x的版本號(hào)都是針對(duì)于全新的框架Angular。但不能說(shuō)Angular和AngularJS一點(diǎn)關(guān)系都沒(méi)有,你看名字這么像,是吧?!回憶一下AngularJS被人念念不忘的特性,雙向數(shù)據(jù)綁定,MVC,指令,服務(wù),過(guò)濾器,模塊化,臟檢查機(jī)制,依賴注入,Scope,路由,表單校驗(yàn)等等。
看下AngularJS到Angular的過(guò)程中,哪些概念被保留下來(lái),哪些被剔除了(所謂的取其精華,去其糟粕)。
剔除的部分:
ng-controller指令:控制器主要是業(yè)務(wù)邏輯的控制部分
$scope概念:很強(qiáng)大又很復(fù)雜
數(shù)據(jù)雙向綁定:數(shù)據(jù)雙向流通可能導(dǎo)致數(shù)據(jù)的震蕩(故才有最多檢查10次的限制,10次之后還不穩(wěn)定就報(bào)錯(cuò))
保留/改善的部分:
路由嵌套:AngularJS自帶的路由系統(tǒng)是不能嵌套路由的,到了Angular你想怎么嵌套就怎么嵌套
過(guò)濾器(Filter)變成管道(Pipe),概念的變化
依賴注入機(jī)制:直接在構(gòu)造器中注入,還有分層依賴注入的概念
指令寫法:
(事件) ng-click變成(click)
[屬性] href = "{{}}"可以寫成 [href]
[(ngModel)]代替以前的ng-model
*ngFor 代替 ng-repeat,不適用于對(duì)象,適用任何有Symbol.iterator屬性的數(shù)據(jù)結(jié)構(gòu)(能用for...of來(lái)訪問(wèn)),比如數(shù)組,集合等
*ngIf 代替 ng-if,去掉ng-show,ng-hide
對(duì)移動(dòng)端的支持
模版,數(shù)據(jù)綁定,服務(wù),模塊,臟檢查機(jī)制等
新增的部分:
組件化:Angular的核心所在
Typescript作為默認(rèn)的開發(fā)語(yǔ)言
ZoneJS監(jiān)聽所有(可能導(dǎo)致數(shù)據(jù)變化)的異步事件
支持服務(wù)端渲染
Angular CliAngular團(tuán)隊(duì)為開發(fā)者提供了一個(gè)開箱即用(out of the box)的腳手架工具:Angular Cli。我們?cè)僖膊挥脫?dān)心在項(xiàng)目初始化時(shí),要搭建配置一系列的工具,比如webpack,karma,tslint,protractor等。
操作很簡(jiǎn)單,只要運(yùn)行如下命令行就搞定了。
具體的語(yǔ)法教程可參考這里。
安裝之后,文件目錄如下:
my-dream-app e2e // 端到端測(cè)試 app.e2e-spec.ts app.po.ts tsconfig.e2e.json node_modules/... // npm包 src/... // 源碼 angular-cli.json // 配置項(xiàng) .editorconfig // 編輯器配置 .gitignore // git忽略文件配置 karma.conf.js // karma配置 package.json // npm配置 protractor.conf.js // 測(cè)試配置項(xiàng) README.md // 項(xiàng)目說(shuō)明 tsconfig.json // ts編輯器的配置 tslint.json // tslint配置項(xiàng)
我們需要關(guān)注的是src文件夾,這里存放我們所有的源代碼,開發(fā)的時(shí)候基本都在src中。
src app // 代碼的主要文件夾 app.component.css // 根組件樣式 app.component.html // 根組件模版 app.component.spec.ts// 根組件測(cè)試 app.component.ts // 根組件腳本 app.module.ts // 根模塊 assets // 靜態(tài)資源 .gitkeep // 保存空文件夾 environments // 環(huán)境配置 environment.prod.ts environment.ts favicon.ico // 圖標(biāo) index.html // 頁(yè)面主入口 main.ts // 腳本主入口 polyfills.ts // 兼容瀏覽器 styles.css // 全局css樣式 test.ts // 單元測(cè)試主入口模塊
Angular很重要的概念之一仍然是模塊。Angular整個(gè)框架就是由很多個(gè)模塊組成的,而不同的模塊需要從不同的地方導(dǎo)入。打開package.json文件,可以看到依賴的angular包可能是這樣的:
"@angular/common": "^2.3.1", "@angular/compiler": "^2.3.1", "@angular/core": "^2.3.1", "@angular/forms": "^2.3.1", "@angular/http": "^2.3.1", "@angular/platform-browser": "^2.3.1", "@angular/platform-browser-dynamic": "^2.3.1", "@angular/router": "^3.3.1",
來(lái)簡(jiǎn)單看下這些angular包中包含了哪些常用的模塊(至少目前為止,我覺(jué)得常用的)。
@angular/core:這里包含了很多常用的模塊
NgModule:模塊定義裝飾器
Component:組件定義裝飾器
Directive:指令定義裝飾器
Pipe :管道定義裝飾器
PipeTransform:管道接口
Injectable:服務(wù)定義裝飾器
ElmentRef:元素引用
ViewChild:獲取子元素
Render:渲染
Input:接受參數(shù)輸入
Output:事件輸出
EventEmitter:觸發(fā)自定義事件
@angular/common
CommonModule:通用模塊,包含內(nèi)置指令ngIf,ngFor
@angular/forms
FormsModule:定義模版驅(qū)動(dòng)表單
ReactiveFormsModule:定義響應(yīng)式表單
FormGroup, FormArray, FormControl, FormBuilder:響應(yīng)式表單元素
Validators:表單校驗(yàn)
@angular/http
HttpModule:http請(qǐng)求模塊
@angular/router
RouterModule 路由模塊
Routes 路由數(shù)據(jù)結(jié)構(gòu)
@angular/platform-browser
platformBrowser:AoT編譯
BrowserModule:瀏覽器支持,注意該模塊導(dǎo)入了CommonModule,然后導(dǎo)出去,所以引用了這個(gè)模塊也就引用了CommonModule
@angular/platform-browser-dynamic
platformBrowserDynamic:JIT編譯
以上模塊都是Angular框架中的自帶模塊,而我們開發(fā)的完整單元也是模塊。一個(gè)應(yīng)用中至少要有一個(gè)模塊,也就是根模塊。 一些共享的功能屬性我們可以抽象出來(lái),成為共享模塊。然后就是一些特性模塊了。
模塊的組成由組件,服務(wù),指令,管道等等組成,這些概念會(huì)在下面講到。定義模塊的語(yǔ)法如下:
@NgModuel({ declarations: [], // 用到的組件,指令,管道 providers: [], // 依賴注入服務(wù) imports: [], // 導(dǎo)入需要的模塊 exports: [], // 導(dǎo)出的模塊,跨模塊交流 entryComponents: [] // 需提前編譯好的模塊 bootstrap: [] // 設(shè)置根組件 }) export class AppModule { }
所有用到的組件,指令,管道,模塊都需要事先在模塊中聲明好,才能在具體組件中使用。服務(wù)可以在模塊,組件,指令中的providers聲明,也可以直接在運(yùn)行時(shí)提供(參見Trotyl Yu的例子)。
一般情況下,在根模塊的bootstrap中設(shè)置啟動(dòng)的根組件即可,但也可以動(dòng)態(tài)處理(參見Trotyl Yu的例子)。
那如何啟動(dòng)根模塊呢?
在入口腳本中,也就是Angular Cli項(xiàng)目中的main.ts中,啟動(dòng)如下:
// 導(dǎo)入需要模塊 import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; // 根模塊 import { AppModule } from "./app/app.module"; // 編譯啟動(dòng)模塊 platformBrowserDynamic().bootstrapModule(AppModule);
至此,我們對(duì)模塊有所了解,也知道了模塊的定義。
組件自從采用組件化的React大火之后,目前市面上炙手可熱的框架全都采用了組件化的理念,Angular當(dāng)然也不能落后了。可以說(shuō),組件化是Angular的核心理念。按Angular在中國(guó)的布道者大漠窮秋的話來(lái)說(shuō),就是:
Angular的核心概念是組件,模塊化機(jī)制NgModule是為組件化服務(wù)的,實(shí)際上所有其它機(jī)制都是圍繞組件化而來(lái)的。只有從組件化這個(gè)角度才能把握Angular的精神內(nèi)核。
組件通常都是由模版和業(yè)務(wù)邏輯組成,看一下如何用Angular寫一個(gè)很簡(jiǎn)單的組件:
// hello.component.ts import { Component } from "@angular/core"; @Component({ selector: "hello", template: "{{greeting}}
", styles: [`p { color: red;}`] }) export class HelloComponent{ private greeting: string; constructor(){ this.greeting = "Hello, Angular2!"; } } // 使用// 渲染結(jié)果 Hello, Angular2!
定義類HelloComponent的時(shí)候,加上裝飾器@Component(Typescript語(yǔ)法),告訴Angular這個(gè)類是組件類。里面的數(shù)據(jù)稱之為元數(shù)據(jù)(metadata),selector屬性說(shuō)明了該組件對(duì)外的使用標(biāo)記,template就是組件的模版,styles是組件的樣式。而HelloComponent中定義的就是該組件的業(yè)務(wù)邏輯了。
如果模版內(nèi)容太多,可以多帶帶寫在一個(gè)html文件中,用templateUrl屬性引入;同理,樣式文件用styleUrls引入。
組件生命周期正如其他框架的組件,Angular的組件也是有生命周期這個(gè)概念。在不同的階段不同的場(chǎng)景下,可以調(diào)用不同的生命周期函數(shù)鉤子(hook)。
constructor:構(gòu)造器函數(shù),一般用于注入服務(wù)
ngOnChanges:檢測(cè)到輸入數(shù)據(jù)變化,首次觸發(fā)發(fā)生在ngOnInit前。注意對(duì)象的屬性發(fā)生變化時(shí)監(jiān)聽不到
ngOnInit:組件初始化,通常會(huì)設(shè)置一些初始值
ngDoCheck:手動(dòng)觸發(fā)更新檢查
ngAfterContentInit:內(nèi)容初始化到組件之后
ngAfterContentChecked:內(nèi)容變更檢測(cè)之后
ngAfterViewInit:視圖 初始化之后
ngAfterViewChecked:視圖發(fā)生變化檢測(cè)之后,這個(gè)可以用來(lái)保證用戶視圖的及時(shí)更新
ngOnDestroy:組件注銷時(shí)的清理工作,通常用于移除事件監(jiān)聽,退訂可觀察對(duì)象等
具體說(shuō)明可以參考這里。
組件通信可以想像得到,組件化的頁(yè)面結(jié)構(gòu)最終會(huì)形成一顆組件樹。盜一張Vue的圖:
不可避免,我們需要考慮父子組件之間的參數(shù)傳遞問(wèn)題。Anuglar提供的通信方式有如下幾種:
父組件到子組件:父組件用屬性綁定將值傳入,子組件通過(guò)@Input來(lái)接收。
// 父組件 import { Component } from "@angular/core"; @Component({ selector: "hero-parent", template: `heroes
` }) export class HeroParentComponent { heroes = [{ name: "John" }, { name: "Lily" }]; } // 子組件 import { Component, Input } from "@angular/core"; import { Hero } from "./hero"; @Component({ selector: "hero-child", template: ` {{hero.name}}
` }) export class HeroChildComponent { @Input() hero: Hero; }
子組件到父組件:子組件自定義事件用@Output傳出,父組件用事件綁定獲取。
// 子組件 import { Component, EventEmitter, Output } from "@angular/core"; @Component({ selector: "my-voter", template: `{{name}}
` }) export class VoterComponent { @Output() onVoted = new EventEmitter(); vote(agreed: boolean) { this.onVoted.emit(agreed); } } // 父組件 import { Component } from "@angular/core"; @Component({ selector: "vote-taker", template: ` Should mankind colonize the Universe?
Agree: {{agreed}}, Disagree: {{disagreed}}
` }) export class VoteTakerComponent { agreed = 0; disagreed = 0; voters = ["Mr. IQ", "Ms. Universe", "Bombasto"]; onVoted(agreed: boolean) { agreed ? this.agreed++ : this.disagreed++; } }
子組件引用:在父組件模版中添加對(duì)子組件的引用,即可通過(guò)該子組件去訪問(wèn)子組件的方法。
Countdown to Liftoff (via local variable)
{{timer.seconds}}
@ViewChild():類似的,也可以在腳本中用@ViewChild()來(lái)獲取子組件
import { AfterViewInit, ViewChild } from "@angular/core"; import { Component } from "@angular/core"; import { CountdownTimerComponent } from "./countdown-timer.component"; @Component({ selector: "countdown-parent-vc", template: `Countdown to Liftoff (via ViewChild)
{{ seconds() }}` }) export class CountdownViewChildParentComponent implements AfterViewInit { @ViewChild(CountdownTimerComponent) private timerComponent: CountdownTimerComponent; seconds() { return 0; } ngAfterViewInit() { setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0); } start() { this.timerComponent.start(); } stop() { this.timerComponent.stop(); } }
將數(shù)據(jù)保存在服務(wù)中
@ngrx/store:參見【譯】手把手教你用ngrx管理Angular狀態(tài)
模板與數(shù)據(jù)綁定模版說(shuō)白了就是html的內(nèi)容,常規(guī)的html基本都是靜態(tài)內(nèi)容,而模版結(jié)合了框架中的新語(yǔ)法使得html動(dòng)態(tài)化。來(lái)看看Angular中的模版有什么便利的語(yǔ)法:
插值綁定:雙花括號(hào){{}}
我們可以看到上一節(jié)組件例子中的{{greeting}}就是插值綁定。不僅可以獲取變量的值,還可以直接寫表達(dá)式。
屬性(Property)綁定
還有其他的,比如樣式綁定:
注意點(diǎn):property和attribute不一樣,想要綁定attribute,你需要寫成property。比如:
Three-Four
你將會(huì)得到如下錯(cuò)誤信息:
Template parse errors: Can"t bind to "colspan" since it isn"t a known native property
你需要改寫成這樣:
// 或者 One-Two One-Two
事件綁定
可以是原生的事件:click,change,keydown,mousemove等,也可以是自定義事件,也可以是指令事件,比如ngSubmit。
雙向綁定
// 雙向綁定的背后其實(shí)是單向綁定和事件觸發(fā),等價(jià)于下面
注意點(diǎn):使用ngModel,需要引入FormsModule模塊。
還有些內(nèi)置的指令:
模版引用變量(# / ref-)
可以在元素上用#或者ref-前綴來(lái)標(biāo)記這個(gè)元素,然后在其他地方引用。
( )
*ngIf:控制內(nèi)容的有無(wú)
Can you see this?
如果還有else部分,可以如下操作:
Can you see this?else block
*ngFor:循環(huán)
{{i}}: {{hero.name}}
具體的模版語(yǔ)法可以參考這里。
路由一個(gè)模塊有了多個(gè)組件之后,需要用路由來(lái)配置哪個(gè)url呈現(xiàn)哪個(gè)組件。
首先,我們需要在入口頁(yè)面的index.html中配置根路徑:
...... ...
然后創(chuàng)建一個(gè)路由模塊:
import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; ... // 路由配置 const appRoutes: Routes = [ { path: "home", component: HomeComponent }, { path: "heroes", component: HeroesComponent }, { path: "", redirectTo: "/home", pathMatch: "full" }, { path: "**", component: PageNotFoundComponent } ]; @NgModule({ imports: [ RouterModule.forRoot(appRoutes) ], exports: [ RouterModule ] }) export class AppRoutingModule {}
在主模塊中導(dǎo)入配置好的路由模塊:
import { NgModule } from "@angular/core"; import { BrowserModule } from "@angular/platform-browser"; import { FormsModule } from "@angular/forms"; ... @NgModule({ imports: [ BrowserModule, FormsModule, AppRoutingModule ], declarations: [ AppComponent, HomeComponent, HeroesComponent, PageNotFoundComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }
而在頁(yè)面中需要一個(gè)容器
import { Component } from "@angular/core"; @Component({ selector: "my-app", template: `Angular Router
` }) export class AppComponent { }
上面代碼中的routerLink定義了用戶點(diǎn)擊后的路由跳轉(zhuǎn),routerLinkActive定義該路由激活時(shí)的樣式類。
路由上還可以帶上一些索引參數(shù):
{ path: "heroes/:id", component: HeroesComponent },
獲取的方式:
import { ActivatedRoute, Params } from "@angular/router"; ... export class a { constructor( private route: ActivatedRoute ) {} // 路由參數(shù) this.route.params }
當(dāng)模塊很多,路由也很多的時(shí)候,我們可以使用模塊懶加載的方式。懶加載的方式也很簡(jiǎn)單,在配置路由的時(shí)候修改如下即可:
const routes: Routes = [ { // 默認(rèn)轉(zhuǎn)到訂單管理 path: "", redirectTo: "/order", pathMatch: "full" }, { path: "order", loadChildren: "./order/order.module#OrderModule" }, { path: "warehouse", loadChildren: "./warehouse/warehouse.module#WarehouseModule" }, { path: "statistics/sales", component: SalesComponent } ]; // 在子模塊中用RouterModule.forChild import { NgModule } from "@angular/core"; import { RouterModule } from "@angular/router"; import { OrderComponent } from "./order.component"; const orderRoutes = [ { path:"", component: OrderComponent } ]; @NgModule({ imports: [RouterModule.forChild(orderRoutes)], exports: [RouterModule] }) export class OrderRoutingModule { }服務(wù)與依賴注入
服務(wù)是什么概念?可以簡(jiǎn)單地認(rèn)為它是一個(gè)功能模塊,重要在于它是單例對(duì)象,并且可以注入到其他的地方使用。
依賴注入是來(lái)自后端的概念,其實(shí)就是自動(dòng)創(chuàng)建一個(gè)實(shí)例,省去每次需要手動(dòng)創(chuàng)建的麻煩。
在Angular中定義一個(gè)服務(wù)很簡(jiǎn)單,主要在類之前加上@Injectable裝飾器的功能。這是最常見的依賴注入方式useClass,其他具體參見這里。
import { Injectable } from "@angular/core"; @Injectable() export class Service { counter: number = 0; getData(){ return this.counter++; } }
然后在模塊的providers中聲明:
import { Service } from "./service"; ... @NgModule({ imports: [ ... ], declarations: [ ... ], providers: [ Service ], // 注入服務(wù) bootstrap: [...] }) export class AppModule { }
使用的時(shí)候需要在構(gòu)造器中建立關(guān)聯(lián):
import { Component } from "@angular/core"; import { Service } from "./service"; ... @Component({ selector: "my-app", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"] }) export class AppComponent { constructor(public service: Service) { // this.service被成功注入 // 相當(dāng)于 this.service = new Service(); // 然后可以調(diào)用服務(wù) this.service.getData(); } }
由于該服務(wù)是在模塊中注入,所以該模塊中的所有組件使用這個(gè)服務(wù)時(shí),使用的都是同一個(gè)實(shí)例。
除了在模塊中聲明,還可以在組件中聲明。假設(shè)AppComponent下還有組件HomeComponent,此時(shí)我們?cè)?b>AppComponent中注入這個(gè)服務(wù):
import { Component } from "@angular/core"; import { Service } from "./service"; ... @Component({ selector: "my-app", templateUrl: "./app.component.html", styleUrls: ["./app.component.css"], providers: [ Service ], // 注入服務(wù) }) export class AppComponent { constructor(public service: Service) { // this.service被成功注入 // 相當(dāng)于 this.service = new Service(); // 然后可以調(diào)用服務(wù) this.service.getData(); } }
如果HomeComponent也使用了這個(gè)服務(wù),那它使用的將是同一個(gè)實(shí)例。這個(gè)可以從Service中的數(shù)據(jù)變化來(lái)看出。
Angular還有個(gè)分層依賴注入的概念,也就是說(shuō),你可以為任一組件創(chuàng)建自己獨(dú)立的服務(wù)。就像上面的例子,如果想要HomeComponent不和它的父組件同使用一個(gè)服務(wù)實(shí)例的話,只要在該組件中重新注入即可:
... @Component({ selector: "home", templateUrl: "./home.component.html", styleUrls: ["./home.component.css"], providers: [ Service ], // 重新注入服務(wù) }) export class HomeComponent { ... }
對(duì)于前后端的接口,通常會(huì)寫成服務(wù)。下面說(shuō)下請(qǐng)求后端數(shù)據(jù)這塊應(yīng)該怎么寫。在模塊這節(jié)中提過(guò),http有專門的HttpModule模塊處理請(qǐng)求。首先要在模塊中導(dǎo)入HttpModule,然后引入http服務(wù),調(diào)用相應(yīng)的請(qǐng)求方法即可。
import { Injectable } from "@angular/core"; import { Http } from "@angular/http"; import "rxjs/add/operator/toPromise"; @Injectable() export class HttpService { constructor(private http: Http) {} getFromServer():any { return this.http.get(`/data`) .toPromise() .then(res => res.json()) .catch(); } }
由于請(qǐng)求返回的對(duì)象是個(gè)可觀察對(duì)象,可以轉(zhuǎn)成Promise對(duì)象處理。這里需要用到RxJS的toPromise操作符,然后用then去處理返回成功結(jié)果,catch處理失敗情況。這樣就搞定了后端數(shù)據(jù)的請(qǐng)求了。
RxJS又是另外一個(gè)比較高深的話題了,有機(jī)會(huì)深入學(xué)習(xí)一下再聊。
指令Angular的指令概念跟AngularJS的指令差不多,最重要的區(qū)別在于Angular中的組件繼承指令,算是特殊的指令。我們看下用指令的方式去寫組件的簡(jiǎn)單例子:
import { Directive,Input,ElementRef } from "@angular/core"; @Directive({ selector: "hello" }) export class HelloDirective { @Input() name: string; constructor(private el: ElementRef) {} public ngOnInit(): void { this.el.nativeElement.innerText = `hello ${this.name}!`; } } // 使用組件指令// 渲染結(jié)果 hello, Yecao!
不要忘記在使用前先在模塊中聲明哦,我覺(jué)得這是Angular最煩人的一點(diǎn)。
除此之外,還有屬性指令和結(jié)構(gòu)指令,屬性指令只改變?cè)氐臉邮交蛘咝袨椤R獙懗蓪傩灾噶睿枰?b>selector屬性中用[]包裹起來(lái)。來(lái)看簡(jiǎn)單地例子:
import { Directive, ElementRef, Renderer2 } from "@angular/core"; @Directive({ selector: "[highLight]" }) export class HighLightDirective { constructor(private el: ElementRef, private renderer2: Renderer2) { } ngAfterViewInit() { this.renderer2.addClass(this.el.nativeElement, "highlight"); } } // 使用屬性指令這一段會(huì)高亮顯示
結(jié)構(gòu)指令就是模板中提到的ngIf,ngFor等指令,它修改了DOM結(jié)構(gòu)。舉個(gè)例子,重寫*ngIf:
import { Directive, Input, ViewContainerRef, TemplateRef } from "@angular/core"; @Directive({ selector: "[myIf]" }) export class MyIfDirective { constructor(private templateRef: TemplateRef管道(過(guò)濾器), private viewContainer: ViewContainerRef) { } @Input() set appMyIf(condition: boolean) { if (condition) { this.viewContainer.createEmbeddedView(this.templateRef); } else { this.viewContainer.clear(); } } } // 使用結(jié)構(gòu)指令 這一段不會(huì)顯示
管道其實(shí)就是過(guò)濾器,就是叫法不一致而已。主要用于格式化源數(shù)據(jù),而不改變?cè)磾?shù)據(jù)。定義和使用的方式也很簡(jiǎn)單:
import { Pipe, PipeTransform } from "@angular/core"; /* * 訂單取消狀態(tài):默認(rèn)為ALL表示全部,CANCEL表示已取消,NOTCANCEL表示正常 */ @Pipe({ name: "cancelStatus" }) export class CancelStatusPipe implements PipeTransform { transform(status:string, blank: boolean):string { const map = { "ALL": "全部", "NOTCANCEL": "正常", "CANCEL": "已取消", "": "暫無(wú)", } return blank? "特殊情況": map[status]; } }
使用前記得在模塊的declarations聲明,或者導(dǎo)到共享模塊,在共享模塊中導(dǎo)出去。使用如下:
{{ "ALL" | cancelStatus }} // 全部 {{ "ALL" | cancelStatus: true }} // 特殊情況
Angular內(nèi)置了一些管道:
// 日期 DatePipe {{ expression | date:"MM/dd/yy" }} // 數(shù)字 DecimalPipe,digitInfo的組成 {minIntegerDigits}.{minFractionDigits}-{maxfractionDigits} // minIntegerDigits:整數(shù)部分保留最小的位數(shù),默認(rèn)值為1. // minFractionDigits:小數(shù)部分保留最小的位數(shù),默認(rèn)值為0. // maxFractionDigits:小數(shù)部分保留最大的位數(shù),默認(rèn)值為3. {{ expression | number[:digitInfo] }} // 大寫 {{ expression | uppercase }} // 小寫 {{ expression | lowercase }}后語(yǔ)
由于篇幅的限制,Angular的每個(gè)特性都點(diǎn)到為止,只是講了一些基本概念和使用方法(我也只會(huì)這點(diǎn)而已),讓你在項(xiàng)目中會(huì)用。還有一塊項(xiàng)目中肯定會(huì)用到的是表單及其校驗(yàn),這是個(gè)大頭,還是放在下一篇多帶帶拎出來(lái)說(shuō)吧。
如果你看到了這里,謝謝你花了那么多時(shí)間閱讀。最近剛淘了視頻,出自這里。 跟大家分享一下,鏈接: http://pan.baidu.com/s/1c2CGkVY 密碼: xwg6。
整體來(lái)說(shuō),接觸Angular2不到一個(gè)月的時(shí)候,現(xiàn)在項(xiàng)目開發(fā)中。簡(jiǎn)單說(shuō)下我的學(xué)習(xí)路徑:
大致瀏覽了下有關(guān)Angular2的文章,跟Angular1的比較,有個(gè)大體的印象
看參考資料中的幾個(gè)視頻教程,我覺(jué)得蠻不錯(cuò)的,讓我對(duì)Angular2有個(gè)整體的概念
參考官網(wǎng)教程做了一下英雄展示板的例子
開始上手開發(fā),邊開發(fā)邊去看文檔
開發(fā)的時(shí)候可以嘗試一些新的知識(shí)點(diǎn),比如多模塊,共享模塊,路由懶加載,自定義表單驗(yàn)證指令,響應(yīng)式表單,ngrx狀態(tài)管理等等
總結(jié)輸出,也就是現(xiàn)在在寫的這邊博客
參考資料
Angular官網(wǎng)(英文)
Angular Cli
Angular官網(wǎng)(中文)
官網(wǎng)英雄展示板例子
英文視頻教程
Angular2一小時(shí)快速入門
大漠窮秋 Angular2 0視頻教程
angularjs 1 和 2區(qū)別,這才是Angular2的靈魂!
Redux你的Angular 2應(yīng)用--ngRx使用體驗(yàn)
Angular 4 指令快速入門
本文首發(fā)于野草園,轉(zhuǎn)載請(qǐng)注明出處。不當(dāng)之處,歡迎批評(píng)指正!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/83824.html
摘要:基本類型在中,提供了一下基本數(shù)據(jù)類型布爾類型數(shù)據(jù)類型字符串類型數(shù)組類型元組類型枚舉類型任意值類型和類型類型其中元組枚舉任意值類型和類型是有別與的特有類型。布爾類型布爾類型是最簡(jiǎn)單的數(shù)據(jù)類型,只有和兩種值。 學(xué)習(xí)Angular 2 , 《揭秘Angular 2》讀書筆記。Angular2 選擇 TypeScript 作為其官方最主要的構(gòu)建語(yǔ)音,這意味著掌握 TypeScript 語(yǔ)音將更...
摘要:聲明和結(jié)構(gòu)在中,支持和這樣的聲明方式。解構(gòu)就是將聲明的一組變量與相同結(jié)構(gòu)的數(shù)組或者對(duì)象的元素?cái)?shù)值一一對(duì)應(yīng),并將變量相對(duì)應(yīng)元素進(jìn)行賦值。 學(xué)習(xí)Angular 2 , 《揭秘Angular 2》讀書筆記。Angular2 選擇 TypeScript 作為其官方最主要的構(gòu)建語(yǔ)音,這意味著掌握 TypeScript 語(yǔ)音將更有利于高效地開發(fā) Angular 應(yīng)用。 聲明和結(jié)構(gòu) 在TypeScr...
摘要:發(fā)布訂閱現(xiàn)在每個(gè)人應(yīng)該都用微信吧,一個(gè)人可以關(guān)注多個(gè)公眾號(hào),多個(gè)人可以同時(shí)關(guān)注相同的公眾號(hào)。公眾號(hào)每周都會(huì)更新內(nèi)容,并推送給我們,把寫好的文章在微信管理平臺(tái)更新就好了,點(diǎn)擊推送,就相當(dāng)于發(fā)布。 什么是MVVM MVVM——Model-View-ViewModle的縮寫,MVC設(shè)計(jì)模式的改進(jìn)版。Model是我們應(yīng)用中的數(shù)據(jù)模型,View是我們的UI層,通過(guò)ViewModle,可以把我們M...
摘要:模塊模塊是自聲明的,兩個(gè)模塊之間的關(guān)系是通過(guò)在文件級(jí)別上使用和來(lái)建立的。類似地,我們必須通過(guò)導(dǎo)入其他模塊導(dǎo)出的變量函數(shù)類等。模塊使用模塊加載器去導(dǎo)入它的依賴,模塊加載器在代碼運(yùn)行時(shí)會(huì)查找并加載模塊間的所有依賴。 學(xué)習(xí)Angular 2 , 《揭秘Angular 2》讀書筆記。Angular2 選擇 TypeScript 作為其官方最主要的構(gòu)建語(yǔ)音,這意味著掌握 TypeScript 語(yǔ)...
閱讀 3236·2021-11-24 10:43
閱讀 4197·2021-11-24 10:33
閱讀 3771·2021-11-22 09:34
閱讀 2125·2021-10-11 10:58
閱讀 3732·2021-10-11 10:58
閱讀 859·2021-09-27 13:36
閱讀 3579·2019-08-30 15:54
閱讀 2965·2019-08-29 18:41