ng2 體驗報告、總結

當然,現在 angular 最新的版本已經出到 5.0 了,現在纔來說 ng2 有點老套了,只是最近忽然的從 react 的項目組轉到了做 angular v2 (ng2) 的項目組,同時對谷歌和微軟的”孩子”也比較感興趣,所以還是有必要好好學習一下的。

上手了一陣子,大概摸清了 ng2 的套路,其實在此之前,對於習慣了 React、 Vue 開發模式的我來說,對於 ng2 是有一定的誤解的。過去的我一直以爲 ng2 只是簡單的視圖框架,就是一個簡單的模板系統,現在看來我是錯了,較之於 React、 Vue 複雜的項目構建來說, ng2 纔是真正的框架啊,如果你有一定的後端基礎,你一定能很快的理解 ng2 知識體系, 而且你也會明白 ng2 作爲一個框架對於開發效率的提升。

關於學習網站

學習 ng2 最好的就是看官網了,當然所有的語言都是一樣的,以下是幾個可能需要經常去逛的網站。

  1. angular-cli 腳手架工具,快速構建項目;
  2. angular 官網,最新的已經是 V5 版本了,可以繼續深入學習;
  3. Rx.js 中文速查手冊;
  4. javascript 的超集 typescript;
  5. 待補……

重要概念

有關於 ng2 幾個重要的概念如下:

  • 腳手架 ( scaffold )
  • 指令( directive )
  • 管道 ( pipe )
  • 路由 ( router )
  • 父子組件通信 ( @input & @output )
  • 模塊 ( model )
  • 服務 ( service )
  • Rxjs ( Oberverable )
  • 依賴注入 ( injectable )

當然,贅述官方的文檔不是我想要的,我更希望通過我個人的理解來介紹這幾個知識點(或許有錯誤)

腳手架 ( scaffold )

嘮叨一句:一般來說,腳手架這個東西,只有新手小白或者大牛會喜歡用,往往處於中間層的大佬們是比較鄙視的,因爲這讓程序變得沒有技術含量,或者,被一些低級的腳手架給坑到。不過話說回來,使用好的腳手架的確能讓讓你的開發更加幸福,與其打開另一個文件複製代碼,爲何不讓腳手架來給你生成呢。

ng2 (angular) 使用的腳手架是官方提供的 angular-cli ,常用的幾個操作如下:

生成對象 命令 注意事項
project ng new PROJECT-NAME 生成新項目
debug ng serve –host 0.0.0.0 –port 4201 啓動本地服務
Component ng g component my-new-component 生成 component
Directive ng g directive my-new-directive 生成自定義指令
Pipe ng g pipe my-new-pipe 生成自定義管道
Service ng g service my-new-service 生成服務
Class ng g class my-new-class 生成類,幾乎不用
Guard ng g guard my-new-guard 生成自定義路由嚮導,通用攔截等
Interface ng g interface my-new-interface 生成接口
Enum ng g enum my-new-enum 生成自定義枚舉文件
Module ng g module my-module 生成自定義module

以上常用的幾個命令參數同樣的路徑模式,意思就是你使用 ng new ./test 這樣的格式也是可以的。

指令( directive )

指令系統是 angular 的一大特色,當你寫 react 你一定特別希望也有自己的指令系統(當然這是玩笑話,因爲 angular 是沒有用 vdom 的)。 在開發過程中,你一定與遇到過如下的指令:

常見結構性指令 *ngIf *ngFor *ngSwitch 的用法:

<!-- 來自官網的英雄榜例子 -->

<div *ngIf="hero" >{{hero.name}}</div>

<ul>
  <li *ngFor="let hero of heroes">{{hero.name}}</li>
</ul>

<div [ngSwitch]="hero?.emotion">
  <app-happy-hero    *ngSwitchCase="'happy'"    [hero]="hero"></app-happy-hero>
  <app-sad-hero      *ngSwitchCase="'sad'"      [hero]="hero"></app-sad-hero>
  <app-confused-hero *ngSwitchCase="'app-confused'" [hero]="hero"></app-confused-hero>
  <app-unknown-hero  *ngSwitchDefault           [hero]="hero"></app-unknown-hero>
</div>

ng-template ng-container

還有一些常用來和結構性指令結合使用的語法,類似 ng-template ng-container 這些。 關於這兩個模板語法,其實並不是有必須要使用的必要,但在很多時候,合理的使用可以讓你的代碼更加語義化,或者說更加優美。關於這兩個,我怕我解釋不當,官網給了兩個比較好的例子:

當然,ng-template 另外的一個用途是 作爲動態組件加載器

自定義指令

用上面的腳手架生成最方便,也不容易出錯。如下,生成一個 名爲check 的指令:

<!-- 執行 ng g directive -->
ng g directive 

<!-- 自定義生成示例,並已在 當前 model 聲明 -->
import { Directive } from '@angular/core';

@Directive({
  selector: '[check]'
})
export class CheckDirective {

  constructor() { }

}

<!--在html模板中使用-->
<input check="xxx" >

問題: 官文文檔會看到一種 屬性型指令 和 結構性指令 ,兩者有什麼區別?

答: 結構型指令 — 通過添加和移除 DOM 元素改變 DOM 佈局的指令,專注於佈局,ngIf 這種。
屬性型指令 — 改變元素、組件或其它指令的外觀和行爲的指令,專注於內部屬性,ngClass 這種。兩種都可以自定義。

管道 ( pipe )

如果習慣了 bash 命令的童鞋,一定對 管道 很熟悉, 你可能經常會見到 ls xxx | grep xxx 這種的寫法,其實 ng 中的 管道 和這個其實是一個意思,寫法都是一樣的,通過 “|” 來分割,不過 ng 的明顯要弱一些,ng 中管道的常見用法都是用來格式化錢幣、數值精度、日期格式化這些操作。

內置管道

ng 內置了一些管道,比如DatePipe、UpperCasePipe、LowerCasePipe、CurrencyPipe和PercentPipe。 它們全都可以直接用在任何模板中。

常見的內置管道

自定義管道

當內置的管道不能滿足需求的時候,往往我們需要自定義自己的管道。我們可以使用 ng g pipe my-new-pipe 來生成自定義管道,如下是一個簡單的 money 格式化的例子,對屬於任意的數值,進行金額的精度控制,當然底層其實還是使用了內置的 DecimalPipe 。

import { Pipe } from '@angular/core';
import { DecimalPipe } from '@angular/common';

@Pipe({
  name: 'money'
})
export class MoneyPipe {

  constructor(protected decimalPipe: DecimalPipe) {

  }

  public transform(value: any, digits?: string): string | null {
    value = parseFloat(value) || 0;
    return this.decimalPipe.transform(value, digits);

  }

}

在需要格式化金額的地方,比如我們要保留兩位小數,我們可以這麼用,{{ 10.2222 | money:'1.2-2'}},具體第二個精度的使用方法可以參考

路由 ( router )

路由重定向

可以這麼寫:

export const routes: Routes = [
  { path: '', redirectTo: 'A', pathMatch: 'full' },
  { path: 'a', component: A },
  { path: 'b', component: B, child:{
    [
      { path: '', redirectTo: 'b-a', pathMatch: 'full' },
      { path: 'b-a', component: ba },
      { path: 'b-b', component: bb }
    ]
  } }
];

路由跳轉

可以這麼寫:

<a [routerLink]="['/a']">a</a>

也可以這麼寫:

this.router.navigate(['/a']);

路由參數

比如一個通知列表,點擊不同的通知可以鏈接到不同的通知內容。

路由配置:

export const routes: Routes = [
  { path: '', redirectTo: 'A', pathMatch: 'full' },
  { path: 'notice-list', component: A },
  { path: 'notice-content/:id', component: B }
];

在 notice-list 設置路由跳轉:

this.router.navigate(['/notice-content'],id);
this.router.navigate(['/notice-content'],params);

讀取路由參數

this.route.params.subscribe(params => {
   console.log(params['id']);
});

this.route.queryParams.subscribe(params => {
   console.log(params);
});

路由攔截

使用 ng g guard login 來快速生成。

import { CanActivate } from '@angular/router';
import { Injectable } from '@angular/core';
import { LoginService } from './login-service';

@Injectable()
export class LoginRouteGuard implements CanActivate {

  constructor(private loginService: LoginService) {}

  canActivate() {
    return this.loginService.isLoggedIn();
  }
}

父子組件通信 ( @input & @output )

父組件向子組件傳值

父組件使用 [data]='{}' 向子組件接收值,子組件通過 @input() data 來接收。

子組件向父組件傳值

一般用於封裝的組件。

在子組件中,使用

@Output() outData = new EventEmitter<string>();
……
this.outData.emit(data);

在父組件中獲取,定義一個 getData 事件

<a (outData)='getData()'></a>

模塊 ( model )

其實模塊這個東西現在一點都不陌生,主流的編程框架都使用了模塊化的編程方式。官方的文檔是這麼介紹的:

Angular 模塊是帶有 @NgModule 裝飾器函數的類。 @NgModule接收一個元數據對象,該對象告訴 Angular 如何編譯和運行模塊代碼。 它標記出該模塊擁有的組件、指令和管道, 並把它們的一部分公開出去,以便外部組件使用它們。 它可以嚮應用的依賴注入器中添加服務提供商。

我們理解起來就是,一個 Angular模塊 = 接收元數據對象(metadata)+ 暴露部分便於外部組件訪問。 如果不清楚什麼是 元數據 的,可以看下官方的介紹

服務 ( service )

在後端編程中經常會用到 服務 ( service ), 我個人的理解是,服務就是可高度抽象且與業務邏輯耦合低的一系列操作。比如所有應用場景下的登錄都需要一個公用的驗證碼,那麼生成驗證碼的這個功能就可以抽象成爲一個服務,服務不是必須的,但是適當寫服務會讓代碼耦合度降低,是一種好的編程習慣。

截止到目前,我用的 ng 中的服務一般是用作某一個模塊的請求封裝,或者是日期的一些特殊操作,就像是一個工廠方法庫一樣。

Rxjs ( Oberverable )

關於異步請求,ng2 自帶的 http 模塊返回的就是一個 Oberverable ,所以在項目中引入 Rx.js 自然無可厚非。官方評價爲 promise 的超集,使用起來的確和 promise 很像,應該說是更加強大。但是正因爲強大,導致要記的方法確實不少,直接戳一個中文api

依賴注入 ( injectable )

依賴注入其實之前也接觸過一些, 依賴注入的目的在我看來有兩個,一個是降低程序間的耦合性和複雜度,一個是減少複雜對象實例化帶來的擴展問題。

關於依賴注入,這裏有兩篇不錯的可以用來理解的文章(都是基於 java ):

當然 ng 中的依賴出入也差不多,而且實現方式也更優雅,東西挺多,可以看官方文檔

總結

其實也是剛接觸 angularv2 不久,自己也只是結合過去的知識對自己認爲的 ng2 做了一個總結,認識還是比較粗鄙的,行文也比較亂。

寫博客總結的這個習慣,希望自己可以繼續堅持下去,即使只有自己看,hahah……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章