1. 程式人生 > >AngularJS VS Angular(轉)

AngularJS VS Angular(轉)

會有 擔心 max ole 每次 reactive operator ack 整數

---恢復內容開始---

原文鏈接:https://zhuanlan.zhihu.com/p/27696268

這篇是在知乎上看到的, 原文鏈接附上。覺得很不錯, 就自己抄過來了。

AngularJS最大版本號只有1.x, 2.x/4.x的版本號都是針對於全新的框架Angular。但是也不能說Angular 和 AngularJS 一點關系都沒有。

提一下AngularJS 的特性:雙向數據綁定,MVC,指令,服務,過濾器,模塊化,臟檢查機制,依賴註入,scope,路由,表單校驗等等。

看下AngularJS 到 Angular的過程中,哪些概念被留下來, 哪些被提剔除了(所謂的取其精華,去其糟粕)。

提出的部分:

  • ng-controller指令:控制器主要是業務邏輯的控制部分
  • $scope概念:很輕大有很復雜(我一直沒弄懂)
  • 數據的雙向綁定:數據雙向流通可能導致數據的震蕩(所以會有最多檢查10次的限制,10次之後還不穩定就會報錯)

保留/改善的部分:

  • 路由嵌套:AngularJS自帶的路由系統是不能嵌套路由的, 到了Angular中可以隨意嵌套
  • 過濾器(Filter)變成管道(Pipe),概念的變化
  • 依賴註入機制:直接在構造器中註入,還有分層依賴註入的概念
  • 指令寫法:
    • ng-click-> (click)
    • [屬性]href="{{}}" 可以寫成[href]
    • [(ngModel)] 代替以前的ng-model
    • *ngFor 代替ng-repeat,不適用於對象,適用於任何有Symbol.iterator屬性的數據結構(能用for...of來訪問) ,比如數據,集合等
    • *ngIf 代替ng-if,去掉ng-show,ng-hide
  • 對移動端的支持
  • 模板,數據綁定,服務,模塊,臟檢查機制等

新增的部分:

  • 組件化:Angular的核心所在
  • Typescript作為默認的開發語言
  • ZoneJS 監聽所有(有可能導致數據變化)的異步事件
  • 支持服務端渲染

Angular Cli

Angular團隊為開發者提供了一個開箱即用(out of the box)的腳手架工具:Angular Cli.我們再也不用擔心在項目初始化時,要搭建配置一系列的工具,比如webpack,karma,tslint,protractor等。

操作很簡單,只要運行如下命令行就搞定了。

技術分享圖片

具體的語法教程可參考這裏。

安裝之後,文件目錄如下:

    my-dream-app
    e2e                      // 端到端測試
        app.e2e-spec.ts
        app.po.ts
        tsconfig.e2e.json
    node_modules/...         // npm包
    src/...                  // 源碼
    angular-cli.json         // 配置項
    .editorconfig            // 編輯器配置
    .gitignore               // git忽略文件配置
    karma.conf.js            // karma配置
    package.json             // npm配置
    protractor.conf.js       // 測試配置項
    README.md                // 項目說明
    tsconfig.json            // ts編輯器的配置
    tslint.json              // tslint配置項

我們需要關註的是src文件夾,這裏存放我們所有的源代碼,開發的時候基本都在src中。

src
    app                      // 代碼的主要文件夾
        app.component.css    // 根組件樣式
        app.component.html   // 根組件模版
        app.component.spec.ts// 根組件測試
        app.component.ts     // 根組件腳本
        app.module.ts        // 根模塊
    assets                   // 靜態資源
        .gitkeep             // 保存空文件夾
    environments             // 環境配置
        environment.prod.ts
        environment.ts
    favicon.ico              // 圖標
    index.html               // 頁面主入口
    main.ts                  // 腳本主入口
    polyfills.ts             // 兼容瀏覽器
    styles.css               // 全局css樣式
    test.ts                  // 單元測試主入口

模塊

Angular很重要的概念之一仍然是模塊。Angular整個框架就是由很多個模塊組成的,而不同的模塊需要從不同的地方導入。打開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",

來簡單看下這些angular包中包含了哪些常用的模塊(至少目前為止,我覺得常用的)。

  • @angular/core:這裏包含了很多常用的模塊
    • NgModule:模塊定義裝飾器
    • Component:組件定義裝飾器
    • Directive:指令定義裝飾器
    • Pipe :管道定義裝飾器
    • PipeTransform:管道接口
    • Injectable:服務定義裝飾器
    • ElmentRef:元素引用
    • ViewChild:獲取子元素
    • Render:渲染
    • Input:接受參數輸入
    • Output:事件輸出
    • EventEmitter:觸發自定義事件
  • @angular/common
    • CommonModule:通用模塊,包含內置指令ngIf,ngFor
  • @angular/forms
    • FormsModule:定義模版驅動表單
    • ReactiveFormsModule:定義響應式表單
    • FormGroup, FormArray, FormControl, FormBuilder:響應式表單元素
    • Validators:表單校驗
  • @angular/http
    • HttpModule:http請求模塊
  • @angular/router
    • RouterModule 路由模塊
    • Routes 路由數據結構
  • @angular/platform-browser
    • platformBrowser:AoT編譯
    • BrowserModule:瀏覽器支持,註意該模塊導入了CommonModule,然後導出去,所以引用了這個模塊也就引用了CommonModule
  • @angular/platform-browser-dynamic
    • platformBrowserDynamic:JIT編譯

以上模塊都是Angular框架中的自帶模塊,而我們開發的完整單元也是模塊。一個應用中至少要有一個模塊,也就是根模塊。 一些共享的功能屬性我們可以抽象出來,成為共享模塊。然後就是一些特性模塊了。

模塊的組成由組件,服務,指令,管道等等組成,這些概念會在下面講到。定義模塊的語法如下:

@NgModuel({
    declarations: [],   // 用到的組件,指令,管道
    providers: [],      // 依賴註入服務 
    imports: [],        // 導入需要的模塊
    exports: [],        // 導出的模塊,跨模塊交流
    entryComponents: [] // 需提前編譯好的模塊
    bootstrap: []       // 設置根組件
    
})
export class AppModule { }
所有用到的組件,指令,管道,模塊都需要事先在模塊中聲明好,才能在具體組件中使用。服務可以在模塊,組件,指令中的providers聲明,也可以直接在運行時提供(參見Trotyl Yu的例子)。

一般情況下,在根模塊的bootstrap中設置啟動的根組件即可,但也可以動態處理(參見Trotyl Yu的例子)。

那如何啟動根模塊呢?

在入口腳本中,也就是Angular Cli項目中的main.ts中,啟動如下:

// 導入需要模塊
import { platformBrowserDynamic } from @angular/platform-browser-dynamic;

// 根模塊
import { AppModule } from ./app/app.module;

// 編譯啟動模塊
platformBrowserDynamic().bootstrapModule(AppModule);

至此,我們對模塊有所了解,也知道了模塊的定義。

組件

自從采用組件化的React大火之後,目前市面上炙手可熱的框架全都采用了組件化的理念,Angular當然也不能落後了。可以說,組件化是Angular的核心理念。按Angular在中國的布道者的話來說,就是:

Angular的核心概念是組件,模塊化機制NgModule是為組件化服務的,實際上所有其它機制都是圍繞組件化而來的。只有從組件化這個角度才能把握Angular的精神內核。

組件通常都是由模版和業務邏輯組成,看一下如何用Angular寫一個很簡單的組件:

// hello.component.ts

import { Component } from @angular/core;

@Component({              
    selector: hello,
    template: <p> {{greeting}} </p>,
    styles: [`p { color: red;}`]
})
export class HelloComponent{
    private greeting: string;
    constructor(){
        this.greeting = Hello, Angular2!;
    }
}

// 使用
<hello></hello>

// 渲染結果
<hello>
    <p> Hello, Angular2! </p> 
</hello>

定義類HelloComponent的時候,加上裝飾器@Component(Typescript語法),告訴Angular這個類是組件類。裏面的數據稱之為元數據(metadata),selector屬性說明了該組件對外的使用標記,template就是組件的模版,styles是組件的樣式。而HelloComponent中定義的就是該組件的業務邏輯了。

如果模版內容太多,可以單獨寫在一個html文件中,用templateUrl屬性引入;同理,樣式文件用styleUrls引入。

組件生命周期

正如其他框架的組件,Angular的組件也是有生命周期這個概念。在不同的階段不同的場景下,可以調用不同的生命周期函數鉤子(hook)。

技術分享圖片

  • constructor:構造器函數,一般用於註入服務
  • ngOnChanges:檢測到輸入數據變化,首次觸發發生在ngOnInit前。註意對象的屬性發生變化時監聽不到
  • ngOnInit:組件初始化,通常會設置一些初始值
  • ngDoCheck:手動觸發更新檢查
    • ngAfterContentInit:內容初始化到組件之後
    • ngAfterContentChecked:內容變更檢測之後
    • ngAfterViewInit:視圖 初始化之後
    • ngAfterViewChecked:視圖發生變化檢測之後,這個可以用來保證用戶視圖的及時更新
  • ngOnDestroy:組件註銷時的清理工作,通常用於移除事件監聽,退訂可觀察對象等

具體說明可以參考這裏。

組件通信

可以想像得到,組件化的頁面結構最終會形成一顆組件樹。盜一張Vue的圖:

技術分享圖片

不可避免,我們需要考慮父子組件之間的參數傳遞問題。Anuglar提供的通信方式有如下幾種:

  • 父組件到子組件:父組件用屬性綁定將值傳入,子組件通過@Input來接收。
// 父組件
import { Component } from @angular/core; 
 
@Component({
  selector: hero-parent,
  template: `<h2> heroes </h2>
    <hero-child *ngFor="let hero of heroes"
      [hero]="hero" >
    </hero-child>
  `
})
export class HeroParentComponent {
  heroes = [{
    name: John
  }, {
    name: Lily
  }]; 
}

// 子組件
import { Component, Input } from @angular/core;

import { Hero } from ./hero;
 
@Component({
  selector: hero-child,
  template: `
    <h3>{{hero.name}}</h3> 
  `
})
export class HeroChildComponent {
  @Input() hero: Hero; 
}
  • 子組件到父組件:子組件自定義事件用@Output傳出,父組件用事件綁定獲取。
// 子組件
import { Component, EventEmitter, Output } from @angular/core;

@Component({
  selector: my-voter,
  template: `
    <h4>{{name}}</h4>
    <button (click)="vote(true)">Agree</button> 
  `
})
export class VoterComponent { 
  @Output() onVoted = new EventEmitter<boolean>(); 
 
  vote(agreed: boolean) {
    this.onVoted.emit(agreed); 
  }
}

// 父組件
import { Component } from @angular/core;

@Component({
  selector: vote-taker,
  template: `
    <h2>Should mankind colonize the Universe?</h2>
    <h3>Agree: {{agreed}}, Disagree: {{disagreed}}</h3>
    <my-voter *ngFor="let voter of voters"
      [name]="voter"
      (onVoted)="onVoted($event)">
    </my-voter>
  `
})
export class VoteTakerComponent {
  agreed = 0;
  disagreed = 0;
  voters = [Mr. IQ, Ms. Universe, Bombasto];
 
  onVoted(agreed: boolean) {
    agreed ? this.agreed++ : this.disagreed++;
  }
}
  • 子組件引用:在父組件模版中添加對子組件的引用,即可通過該子組件去訪問子組件的方法。
<h3>Countdown to Liftoff (via local variable)</h3>
<button (click)="timer.start()">Start</button>
<button (click)="timer.stop()">Stop</button>
<div class="seconds">{{timer.seconds}}</div>
<countdown-timer #timer></countdown-timer>
  • @ViewChild():類似的,也可以在腳本中用@ViewChild()來獲取子組件
import { AfterViewInit, ViewChild } from @angular/core;
import { Component }                from @angular/core;
import { CountdownTimerComponent }  from ./countdown-timer.component;
 
@Component({
  selector: countdown-parent-vc,
  template: `
  <h3>Countdown to Liftoff (via ViewChild)</h3>
  <button (click)="start()">Start</button>
  <button (click)="stop()">Stop</button>
  <div class="seconds">{{ seconds() }}</div>
  <countdown-timer></countdown-timer>
  `
})
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(); }
}
  • 將數據保存在服務中
  • @ngrx/store:參見【譯】手把手教你用ngrx管理Angular狀態

模板與數據綁定

模版說白了就是html的內容,常規的html基本都是靜態內容,而模版結合了框架中的新語法使得html動態化。來看看Angular中的模版有什麽便利的語法:

  • 插值綁定:雙花括號{{}}

我們可以看到上一節組件例子中的{{greeting}}就是插值綁定。不僅可以獲取變量的值,還可以直接寫表達式。

  • 屬性(Property)綁定
<input [value]=myData>

還有其他的,比如樣式綁定:

<div [ngClass]="{special: isSpecial}"></div>
註意點:property和attribute不一樣,想要綁定attribute,你需要寫成property。比如:
<tr><td colspan="{{1 + 1}}">Three-Four</td></tr>

你將會得到如下錯誤信息:

Template parse errors:
Can‘t bind to ‘colspan‘ since it isn‘t a known native property

你需要改寫成這樣:

<tr><td [attr.colspan]="1 + 1">One-Two</td></tr>
// 或者
<tr><td attr.colspan="{{1 + 1}}">One-Two</td></tr>
  • 事件綁定
<input (keyup)=handle($event) >

可以是原生的事件:click,change,keydown,mousemove等,也可以是自定義事件,也可以是指令事件,比如ngSubmit。

  • 雙向綁定
<input [(ngModel)] = data>
// 雙向綁定的背後其實是單向綁定和事件觸發,等價於下面
<input [ngModel]="data" (ngModelChange)="data=$event">

註意點:使用ngModel,需要引入FormsModule模塊。

還有些內置的指令:

  • 模版引用變量(# / ref-)

可以在元素上用#或者ref-前綴來標記這個元素,然後在其他地方引用。

<input #fax placeholder="fax number">
( <input ref-fax placeholder="fax number"> )
<button (click)="callFax(fax.value)">Fax</button>
  • *ngIf:控制內容的有無
<div *ngIf="show"> Can you see this? </div>

如果還有else部分,可以如下操作:

<div *ngIf="show; else elseBlock"> Can you see this? </div>
<ng-template #elseBlock>  else block   </ng-template>
  • *ngFor:循環
<div *ngFor="let hero of heroes; let i=index> {{i}}: {{hero.name}}</div>

具體的模版語法可以參考這裏。

路由

一個模塊有了多個組件之後,需要用路由來配置哪個url呈現哪個組件。

首先,我們需要在入口頁面的index.html中配置根路徑:

...
<head>
<base href="/">
...
</head>
...

然後創建一個路由模塊:

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 {}

在主模塊中導入配置好的路由模塊:

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 { }

而在頁面中需要一個容器<router-outlet></router-outlet>去承載:

import { Component } from @angular/core;
 
@Component({
  selector: my-app,
  template: `
    <h1>Angular Router</h1>
    <nav>
      <a routerLink="/home" routerLinkActive="active">Home</a>
      <a routerLink="/heroes" routerLinkActive="active">Heroes</a>
    </nav>
    <router-outlet></router-outlet>
  `
})
export class AppComponent { }

上面代碼中的routerLink定義了用戶點擊後的路由跳轉,routerLinkActive定義該路由激活時的樣式類。

路由上還可以帶上一些索引參數:

{ path: heroes/:id, component: HeroesComponent },

獲取的方式:

import { ActivatedRoute, Params }   from @angular/router;

...
export class a {
    constructor( 
      private route: ActivatedRoute 
    ) {}
    
    // 路由參數
    this.route.params
}

當模塊很多,路由也很多的時候,我們可以使用模塊懶加載的方式。懶加載的方式也很簡單,在配置路由的時候修改如下即可:

const routes: Routes = [
    {    // 默認轉到訂單管理
        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 {
}

服務依賴註入

服務是什麽概念?可以簡單地認為它是一個功能模塊,重要在於它是單例對象,並且可以註入到其他的地方使用。

依賴註入是來自後端的概念,其實就是自動創建一個實例,省去每次需要手動創建的麻煩。

在Angular中定義一個服務很簡單,主要在類之前加上@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 ],  // 註入服務
    bootstrap: [...]
})
export class AppModule {
}

使用的時候需要在構造器中建立關聯:

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被成功註入
        // 相當於 this.service = new Service(); 
        // 然後可以調用服務
        this.service.getData();
    }
}

由於該服務是在模塊中註入,所以該模塊中的所有組件使用這個服務時,使用的都是同一個實例。

除了在模塊中聲明,還可以在組件中聲明。假設AppComponent下還有組件HomeComponent,此時我們在AppComponent中註入這個服務:

import { Component } from @angular/core; 
import { Service } from ./service;
...

@Component({
    selector: my-app,
    templateUrl: ./app.component.html,
    styleUrls: [./app.component.css],
    providers: [ Service ],  // 註入服務
})
export class AppComponent {
    constructor(public service: Service) {
        // this.service被成功註入
        // 相當於 this.service = new Service(); 
        // 然後可以調用服務
        this.service.getData();
    }
}

由於該服務是在模塊中註入,所以該模塊中的所有組件使用這個服務時,使用的都是同一個實例。

除了在模塊中聲明,還可以在組件中聲明。假設AppComponent下還有組件HomeComponent,此時我們在AppComponent中註入這個服務:

import { Component } from @angular/core; 
import { Service } from ./service;
...

@Component({
    selector: my-app,
    templateUrl: ./app.component.html,
    styleUrls: [./app.component.css],
    providers: [ Service ],  // 註入服務
})
export class AppComponent {
    constructor(public service: Service) {
        // this.service被成功註入
        // 相當於 this.service = new Service(); 
        // 然後可以調用服務
        this.service.getData();
    }
}

如果HomeComponent也使用了這個服務,那它使用的將是同一個實例。這個可以從Service中的數據變化來看出。

Angular還有個分層依賴註入的概念,也就是說,你可以為任一組件創建自己獨立的服務。就像上面的例子,如果想要HomeComponent不和它的父組件同使用一個服務實例的話,只要在該組件中重新註入即可:

...
@Component({
    selector: home,
    templateUrl: ./home.component.html,
    styleUrls: [./home.component.css],
    providers: [ Service ],  // 重新註入服務
})
export class HomeComponent {
    ...
}

對於前後端的接口,通常會寫成服務。下面說下請求後端數據這塊應該怎麽寫。在模塊這節中提過,http有專門的HttpModule模塊處理請求。首先要在模塊中導入HttpModule,然後引入http服務,調用相應的請求方法即可。

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();
  }
}

由於請求返回的對象是個可觀察對象,可以轉成Promise對象處理。這裏需要用到RxJS的toPromise操作符,然後用then去處理返回成功結果,catch處理失敗情況。這樣就搞定了後端數據的請求了。

RxJS又是另外一個比較高深的話題了,有機會深入學習一下再聊。

指令

Angular的指令概念跟AngularJS的指令差不多,最重要的區別在於Angular中的組件繼承指令,算是特殊的指令。我們看下用指令的方式去寫組件的簡單例子:

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}!`;
    }
}

// 使用組件指令
<hello name="Yecao"></hello>

// 渲染結果
<hello> hello, Yecao! </hello>

不要忘記在使用前先在模塊中聲明哦,我覺得這是Angular最煩人的一點。

除此之外,還有屬性指令和結構指令,屬性指令只改變元素的樣式或者行為。要寫成屬性指令,需要在selector屬性中用[]包裹起來。來看簡單地例子:

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);   
  }  
}

// 使用屬性指令
<p highLight> 這一段會高亮顯示 </p>

結構指令就是模板中提到的*ngIf,ngFor等指令,它修改了DOM結構。舉個例子,重寫ngIf:

import { Directive, Input, ViewContainerRef, TemplateRef } from @angular/core;   

@Directive({   
  selector: [myIf]  
})  

export class MyIfDirective {    

  constructor(private templateRef: TemplateRef<any>,   
      private viewContainer: ViewContainerRef) { }   

  @Input() set appMyIf(condition: boolean) {   
    if (condition) {   
      this.viewContainer.createEmbeddedView(this.templateRef);   
    } else {   
      this.viewContainer.clear();   
    }   
  }  
}  

// 使用結構指令
<p *myIf="false"> 這一段不會顯示 </p>

管道(過濾器)

管道其實就是過濾器,就是叫法不一致而已。主要用於格式化源數據,而不改變源數據。定義和使用的方式也很簡單:

import { Pipe, PipeTransform } from @angular/core; 

/*
 * 訂單取消狀態:默認為ALL表示全部,CANCEL表示已取消,NOTCANCEL表示正常
*/
@Pipe({ name: cancelStatus })
export class CancelStatusPipe implements PipeTransform {
    transform(status:string, blank: boolean):string {
         const map = {
             "ALL": "全部", 
             "NOTCANCEL": "正常",
             "CANCEL": "已取消",
              "": "暫無",  
         }

         return blank? 特殊情況: map[status];
    }
}

使用前記得在模塊的declarations聲明,或者導到共享模塊,在共享模塊中導出去。使用如下:

{{ "ALL" | cancelStatus }}  // 全部
{{ "ALL" | cancelStatus: true }}  // 特殊情況

Angular內置了一些管道:

// 日期 DatePipe
{{ expression | date:"MM/dd/yy" }} 

// 數字 DecimalPipe,digitInfo的組成 {minIntegerDigits}.{minFractionDigits}-{maxfractionDigits}
// minIntegerDigits:整數部分保留最小的位數,默認值為1.
// minFractionDigits:小數部分保留最小的位數,默認值為0.
// maxFractionDigits:小數部分保留最大的位數,默認值為3.
{{ expression | number[:digitInfo] }}

// 大寫
{{ expression | uppercase }}

// 小寫
{{ expression | lowercase }}

參考資料

  • Angular官網(英文)
  • Angular Cli
  • Angular官網(中文)
  • 官網英雄展示板例子
  • 英文視頻教程
  • Angular2一小時快速入門
  • 大漠窮秋 Angular2 0視頻教程
  • angularjs 1 和 2區別,這才是Angular2的靈魂!
  • Redux你的Angular 2應用--ngRx使用體驗
  • Angular 4 指令快速入門

本文首發於野草園,轉載請註明出處。不當之處,歡迎批評指正!

AngularJS VS Angular(轉)