Angular 主要構造塊

Angular 主要分為八大構造塊(也就是八個核心概念):模塊 (module)、組件 (component)、模板 (template)、元數據 (metadata)、數據綁定 (data binding)、指令 (directive)、服務 (service)、依賴注入 (dependency injection)。其中,最核心的一個概念就就組件。

1. 模塊 (module)

Angular 應用是模塊化的,并且 Angular 有自己的模塊系統,它被稱為 Angular 模塊或 NgModules

每個Angular應用至少有一個模塊(根模塊),習慣上命名為AppModule

根模塊在一些小型應用中可能是唯一的模塊,大多數應用會有很多特性模塊,每個模塊都是一個內聚的代碼塊專注于某個應用領域、工作流或緊密相關的功能。

Angular 模塊(無論是根模塊還是特性模塊)都是一個帶有@NgModule裝飾器的類。

下面是一個簡單的根模塊:

// src/app/app.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
  imports:      [ BrowserModule ],
  providers:    [ Logger ],
  declarations: [ AppComponent ],
  exports:      [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

其中重要的屬性是:

  • declarations - 聲明本模塊中擁有的視圖類Angular 有三種視圖類:組件、指令、管道;
  • exports - declarations 的子集,可用于其它模塊的組件;
  • imports - 本模塊聲明的組件模板需要的類所在的其它模塊。用來導入其他自定義模塊,第三方插件模塊;
  • providers - 服務的創建者,并加入到全局服務列表中,可用于應用任何部分;
  • bootstrap - 指定應用的主視圖(稱為根組件),它是所有其它視圖的宿主。只有根模塊才能設置bootstrap屬性。通常在main.ts中引導AppModule,這樣platformBrowserDynamic().bootstrapModule(AppModule)

2. 組件 (component)

組件負責控制屏幕上的一小塊區域,我們稱之為視圖

下面是一個組件的簡單例子:

// src/app/hero-list.component.ts

export class HeroListComponent implements OnInit {
  heroes: Hero[];
  selectedHero: Hero;

  constructor(private service: HeroService) { }

  ngOnInit() {
    this.heroes = this.service.getHeroes();
  }

  selectHero(hero: Hero) { this.selectedHero = hero; }
}

3. 模板 (template)

模板就是HTML文件,但是不是標準的HTML文件,它使用了一些模板語法,模板語法使模板有了自己的邏輯關系,并能夠實現和組件的簡單數據交互。

下面是一個簡單的模板:

// src/app/hero-list.component.html

<h2>Hero List</h2>
<p><i>Pick a hero from the list</i></p>
<ul>
  <li *ngFor="let hero of heroes" (click)="selectHero(hero)">
    {{hero.name}}
  </li>
</ul>
<hero-detail *ngIf="selectedHero" [hero]="selectedHero"></hero-detail>

通常使用ng g component my-component命令產生一個組件包含四個文件:

my-component.css            // 樣式文件
my-component.thml           // 模板
my-component.spec.ts        // 測試文件
my-component.ts         // 這是組件? 通常我們認為這四個文件組成一個組件

4. 元數據 (metadata)

元數據告訴你如何處理一個類。

其實,在Angular中每個組件只是一個類,但是我們可以通過裝飾器來附加元數據告訴Angular這是一個組件。

下面就是HeroListComponent的一些元數據。

// src/app/hero-list.component.ts (metadata)

@Component({   // @Component 將后面的 HeroListComponent 類標記為一個組件
  selector:    'hero-list',
  templateUrl: './hero-list.component.html',
  providers:  [ HeroService ]
})
export class HeroListComponent implements OnInit {
/* . . . */
}

@Component裝飾器能接受一個配置對象, Angular 會基于這些信息創建和展示組件及其視圖。

@Component的配置項包括:

  • selectorCSS選擇器,它告訴Angular在父級HTML中查找<hero-list>標簽,創建并插入該組件。 例如,如果應用的HTML 包含<hero-list></hero-list>Angular就會把HeroListComponent的一個實例插入到這個標簽中;
  • templateUrl:組件HTML 模板的模塊相對地址;
  • providers - 組件所需服務的依賴注入提供商數組。 這是在告訴 Angular:該組件的構造函數需要一個HeroService服務,這樣組件就可以從服務中獲得英雄數據。

到這里你應該可以明白:模板、元數據和組件共同描繪出這個視圖。

5. 數據綁定 (databinding)

數據綁定是Angular中最常用的數據處理模式。數據綁定在模板與對應組件的交互中扮演了重要的角色,在父組件與子組件的通訊中也同樣重要。

下面是一個簡單的例子:

// src/app/hero-list.component.html 

<li>{{hero.name}}</li>
<hero-detail [hero]="selectedHero"></hero-detail>
<li (click)="selectHero(hero)"></li>
  • {{hero.name}}插值表達式<li>標簽中顯示組件的hero.name屬性的值;
  • [hero]屬性綁定把父組件HeroListComponentselectedHero的值傳到子組件HeroDetailComponenthero屬性中;
  • (click) 事件綁定在用戶點擊英雄的名字時調用組件的selectHero方法。

Angular默認沒有雙向綁定,但是,官方推薦這樣來實現雙向綁定:

<input [(ngModel)]="hero.name">

Angular 在每個 JavaScript 事件循環中處理所有的數據綁定,它會從組件樹的根部開始,遞歸處理全部子組件。

6. 指令 (directive)

由于Angular模板是動態的,所以你需要通過指令實現對DOM的轉換。(組件是一個帶模板的指令@Component裝飾器實際上就是一個@Directive裝飾器,只是擴展了一些面向模板的特性。 )

指令分為兩種:結構指令、屬性指令。

a. 結構指令: 通過在 DOM 中添加、移除和替換元素來修改布局。

下面是一個簡單的內置結構指令的例子:

<!-- src/app/hero-list.component.html (structural) -->

<li *ngFor="let hero of heroes"></li>
<hero-detail *ngIf="selectedHero"></hero-detail>
  • *ngFor告訴 Angular 為heroes列表中的每個英雄生成一個<li>標簽。
  • *ngIf表示只有在選擇的英雄存在時,才會包含HeroDetail組件。

b. 屬性指令:修改一個現有元素的外觀或行為。

簡單例子:

<!-- src/app/hero-detail.component.html -->

<input [(ngModel)]="hero.name">

7. 服務 (service)

服務是一個廣義范疇,包括:值、函數,或應用所需的特性。幾乎任何東西都可以是一個服務。 典型的服務是一個類,具有專注的、明確的用途。它應該做一件特定的事情,并把它做好。

例如:

  • 日志服務
  • 數據服務
  • 消息總線
  • 稅款計算器
  • 應用程序配置

組件類應保持精簡。組件本身不從服務器獲得數據、不進行驗證輸入,也不直接往控制臺寫日志。 它們把這些任務委托給服務。所以說服務是跑腿的,服務一般用來處理業務邏輯,被注入在組件當中,服務是全局單例的。也就是說注入到所有組件中的服務是同一個。

一個簡單的例子:

// src/app/hero.service.ts 

export class HeroService {
  private heroes: Hero[] = [];

  constructor(
    private backend: BackendService,
    private logger: Logger) { }

  getHeroes() {
    this.backend.getAll(Hero).then( (heroes: Hero[]) => {
      this.logger.log(`Fetched ${heroes.length} heroes.`);
      this.heroes.push(...heroes); // fill cache
    });
    return this.heroes;
  }
}

8. 依賴注入 (dependency injection)

“依賴注入”是提供類的新實例的一種方式,還負責處理好類所需的全部依賴。大多數依賴都是服務。 Angular 使用依賴注入來提供新組件以及組件所需的服務。

來看注入方式:

// src/app/hero-list.component.ts

constructor(private service: HeroService) { }

注入器維護了一個服務實例的容器,存放著以前創建的實例。 如果所請求的服務實例不在容器中,注入器就會創建一個服務實例,并且添加到容器中,然后把這個服務返回給 Angular。 當所有請求的服務都被解析完并返回時,Angular 會以這些服務為參數去調用組件的構造函數。 這就是依賴注入

通常我們將服務聲明在根模塊,以便在整個應用中使用這個服務。

// src/app/app.module.ts

providers: [
  BackendService,
  HeroService,
  Logger
],

也可以在其他組件中聲明服務,那么這個服務只能用于當前組件。把它注冊在組件級表示該組件的每一個新實例都會有一個服務的新實例。

// src/app/hero-list.component.ts

@Component({
  selector:    'hero-list',
  templateUrl: './hero-list.component.html',
  providers:  [ HeroService ]
})
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,978評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,960評論 2 373

推薦閱讀更多精彩內容