Angular官網教程示例知識點總結

1.背景

在我開始自學Angular的時候,是直接看的Angular的中文官網:
https://angular.cn
官網講得非常細緻,非常專業。其中有個“英雄指南”的示例,我覺得拿來實際操作一番,會學到非常多的東西,如下圖:
在這裏插入圖片描述
下文就是把我當時在這個示例中所學到的知識點,全部總結出來,供大家參考。

2.知識點

2.1 應用的外殼

2.1.1 使用 Angular CLI 創建初始的應用結構

ng new angular-tour-of-heroes

2.1.2 啓動應用服務器

cd angular-tour-of-heroes
ng serve --open

2.1.3 雙花括號表達式

<h1>{{title}}</h1>

雙花括號語法是 Angular 的插值綁定語法。 這個插值綁定的意思是把組件的 title 屬性的值綁定到 HTML 中的 h1 標記中。

2.2 英雄編輯器

2.2.1 使用 Angular CLI 創建一個名爲 heroes 的新組件

ng generate component heroes
CLI 創建了一個新的文件夾 src/app/heroes/,並生成了 HeroesComponent 的三個文件。

2.2.2 @Component裝飾器函數

@Component() 裝飾器表明緊隨它的那個類是一個組件,並提供模板和該組件專屬的元數據。

2.2.3 元數據屬性

CLI 會自動生成了三個元數據屬性:

  1. selector— 組件的選擇器(CSS 元素選擇器)
  2. templateUrl— 組件模板文件的位置。
  3. styleUrls— 組件私有 CSS 樣式表文件的位置。

CSS 元素選擇器 app-heroes 用來在父組件的模板中匹配 HTML 元素的名稱,以識別出該組件。

  • selector:是一個 CSS 選擇器,它會告訴 Angular,一旦在模板 HTML中找到了這個選擇器對應的標籤,就創建並插入該組件的一個實例。 比如,如果應用的 HTML 中包含,Angular 就會在這些標籤中插入一個 HeroListComponent 實例的視圖。
  • templateUrl:該組件的 HTML 模板文件相對於這個組件文件的地址。另外,你還可以用 template 屬性的值來提供內聯的 HTML 模板。 這個模板定義了該組件的宿主視圖。
  • providers:當前組件所需的服務提供商的一個數組。在這個例子中,它告訴 Angular 該如何提供一個 HeroService實例,以獲取要顯示的英雄列表。

2.2.4 生命週期鉤子

ngOnInit 是一個生命週期鉤子,Angular 在創建完組件後很快就會調用 ngOnInit。這裏是放置初始化邏輯的好地方。
始終要 export 這個組件類,以便在其它地方(比如 AppModule)導入它。

2.2.5 管道

<h2>{{hero.name | uppercase}} Details</h2> 

瀏覽器刷新了。現在,英雄的名字顯示成了大寫字母。
綁定表達式中的 uppercase 位於管道操作符( | )的右邊,用來調用內置管道 UppercasePipe。
管道 是格式化字符串、金額、日期和其它顯示數據的好辦法。 Angular 發佈了一些內置管道,而且你還可以創建自己的管道。

2.2.6 雙向數據綁定

[(ngModel)] 是 Angular 的雙向數據綁定語法。
這裏把 hero.name 屬性綁定到了 HTML 的 textbox 元素上,以便數據流可以雙向流動:從 hero.name 屬性流動到 textbox,並且從 textbox 流回到 hero.name 。

2.2.7 AppModule

Angular 需要知道如何把應用程序的各個部分組合到一起,以及該應用需要哪些其它文件和庫。 這些信息被稱爲元數據(metadata)。
有些元數據位於 @Component 裝飾器中,你會把它加到組件類上。 另一些關鍵性的元數據位於 @NgModule 裝飾器中。
最重要的 @NgModule 裝飾器位於頂級類 AppModule 上。

2.3 顯示英雄列表

2.3.1 複寫器*ngFor,用來顯示列表

<h2>My Heroes</h2> 
<ul class="heroes"> 
  <li> 
    <span class="badge">{{hero.id}}</span> {{hero.name}} 
  </li> 
</ul>

現在,把

<li> 

修改成這樣:

<li *ngFor="let hero of heroes">

*ngFor 是一個 Angular 的複寫器(repeater)指令。 它會爲列表中的每項數據複寫它的宿主元素。
在這個例子中:
• li就是 *ngFor 的宿主元素
• heroes 就是來自 HeroesComponent 類的列表。
• 當依次遍歷這個列表時,hero 會爲每個迭代保存當前的英雄對象。

不要忘了 ngFor 前面的星號(*),它是該語法中的關鍵部分。

2.3.2 事件綁定語法click()

<li *ngFor="let hero of heroes" (click)="onSelect(hero)">

這是 Angular 事件綁定 語法的例子。
click 外面的圓括號會讓 Angular 監聽這個 li 元素的 click 事件。 當用戶點擊 li 時,Angular 就會執行表達式 onSelect(hero)。
onSelect() 是 HeroesComponent 上的一個方法,你很快就要寫它。 Angular 會把所點擊的 li 上的 hero 對象傳給它,這個 hero 也就是前面在 *ngFor 表達式中定義的那個。

2.3.3 使用 *ngIf 來根據條件包含或排除一段 HTML

<div *ngIf="selectedHero">
<h2>{{selectedHero.name | uppercase}} Details</h2>
  <div><span>id: </span>{{selectedHero.id}}</div>
  <div>
    <label>name:
      <input [(ngModel)]="selectedHero.name" placeholder="name">
    </label>
  </div>
</div>

當 selectedHero 爲 undefined 時,ngIf 從 DOM 中移除了英雄詳情。因此也就不用擔心 selectedHero 的綁定了。
當用戶選擇一個英雄時,selectedHero 也就有了值,並且 ngIf 把英雄的詳情放回到 DOM 中。

2.3.4 用 class 綁定來切換 CSS 的樣式類

Angular 的 CSS 類綁定機制讓根據條件添加或移除一個 CSS 類變得很容易。 只要把 [class.some-css-class]=“some-condition” 添加到你要施加樣式的元素上就可以了。
在 HeroesComponent 模板中的 li 元素上添加 [class.selected] 綁定,代碼如下:

[class.selected]="hero === selectedHero"

如果當前行的英雄和 selectedHero 相同,Angular 就會添加 CSS 類 selected,否則就會移除它。
最終的 li是這樣的:

<li *ngFor="let hero of heroes"
  [class.selected]="hero === selectedHero"
  (click)="onSelect(hero)">
  <span class="badge">{{hero.id}}</span> {{hero.name}}
</li>

2.4 主從組件

2.4.1 @Input() 裝飾器

@Input() 裝飾器,讓 hero 屬性可以在外部的 HeroesComponent 中綁定。
HeroDetailComponent 模板中綁定了組件中的 hero 屬性,它的類型是 Hero。
打開 HeroDetailComponent 類文件,並導入 Hero 符號。

import { Hero } from '../hero';

hero 屬性必須是一個帶有 @Input() 裝飾器的輸入屬性,因爲外部的 HeroesComponent 組件將會綁定到它。就像這樣:

<app-hero-detail [hero]="selectedHero"></app-hero-detail> 

修改 @angular/core 的導入語句,導入 Input 符號。

import { Component, OnInit, Input } from '@angular/core';

添加一個帶有 @Input() 裝飾器的 hero 屬性。

@Input() hero: Hero;

這就是你要對 HeroDetailComponent 類做的唯一一項修改。 沒有其它屬性,也沒有展示邏輯。這個組件所做的只是通過 hero 屬性接收一個英雄對象,並顯示它。

2.4.2 屬性數據綁定語法,單向數據綁定

把 HeroesComponent.selectedHero 綁定到該元素的 hero 屬性,就像這樣:

<app-hero-detail [hero]="selectedHero"></app-hero-detail> 

[hero]=“selectedHero” 是 Angular 的屬性綁定語法。
這是一種單向數據綁定。從 HeroesComponent 的 selectedHero 屬性綁定到目標元素的 hero 屬性,並映射到了 HeroDetailComponent 的 hero 屬性。

2.5 服務

2.5.1 服務Service

Angular不光有組件component,還有服務service。
使用 Angular CLI 創建一個名叫 hero 的服務。

ng generate service hero 

該命令會在 src/app/hero.service.ts 中生成 HeroService 類的骨架。
服務是在多個“互相不知道”的類之間共享信息的好辦法。
服務類的定義通常緊跟在 “@Injectable()” 裝飾器之後。該裝飾器提供的元數據可以讓你的服務作爲依賴被注入到客戶組件中。

2.5.2 依賴注入

依賴注入(DI)是一種重要的應用設計模式。 Angular 有自己的 DI 框架,在設計應用時通常會用到它,以提升它們的開發效率和模塊化程度。
依賴,是當類需要執行其功能時,所需要的服務或對象。 DI 是一種編碼模式,其中的類會從外部源中請求獲取依賴,而不是自己創建它們。
在 Angular 中,DI 框架會在實例化該類時向其提供這個類所聲明的依賴項。

2.5.3 @Injectable() 服務

這個新的服務導入了 Angular 的 Injectable 符號,並且給這個服務類添加了 @Injectable() 裝飾器。 它把這個類標記爲依賴注入系統的參與者之一。HeroService 類將會提供一個可注入的服務,並且它還可以擁有自己的待注入的依賴。
@Injectable() 裝飾器會接受該服務的元數據對象,就像 @Component() 對組件類的作用一樣。

2.5.4 異步函數簽名

HeroService 必須等服務器給出響應, 而 getHeroes() 不能立即返回英雄數據, 瀏覽器也不會在該服務等待期間停止響應。
HeroService.getHeroes() 必須具有某種形式的異步函數簽名。
它可以使用回調函數,可以返回 Promise(承諾),也可以返回 Observable(可觀察對象)。
這節課,HeroService.getHeroes() 將會返回 Observable,因爲它最終會使用 Angular 的 HttpClient.get 方法來獲取英雄數據,而 HttpClient.get() 會返回 Observable。

2.5.5 可觀察(Observable)的數據

Observable 是 RxJS 庫中的一個關鍵類。
在稍後的 HTTP 教程中,你就會知道 Angular HttpClient 的方法會返回 RxJS 的 Observable。
of(HEROES) 會返回一個 Observable<Hero[]>,它會發出單個值,這個值就是這些模擬英雄的數組。

2.5.6 Observable.subscribe()

上一個版本把英雄的數組賦值給了該組件的 heroes 屬性。 這種賦值是同步的,這裏包含的假設是服務器能立即返回英雄數組或者瀏覽器能在等待服務器響應時凍結界面。
當 HeroService 真的向遠端服務器發起請求時,這種方式就行不通了。
新的版本等待 Observable 發出這個英雄數組,這可能立即發生,也可能會在幾分鐘之後。 然後,subscribe 函數把這個英雄數組傳給這個回調函數,該函數把英雄數組賦值給組件的 heroes 屬性。
使用這種異步方式,當 HeroService 從遠端服務器獲取英雄數據時,就可以工作了。

2.5.7 服務中的服務

把 MessageService 注入到了 HeroService 中,而 HeroService 又被注入到了 HeroesComponent 中。

2.6 路由

2.6.1 路由器

Angular 的最佳實踐之一就是在一個獨立的頂級模塊中加載和配置路由器,它專注於路由功能,然後由根模塊 AppModule 導入它。
路由定義 會告訴路由器,當用戶點擊某個鏈接或者在瀏覽器地址欄中輸入某個 URL 時,要顯示哪個視圖。
典型的 Angular 路由(Route)有兩個屬性:

  1. path:一個用於匹配瀏覽器地址欄中 URL 的字符串。
  2. component:當導航到此路由時,路由器應該創建哪個組件。

如果你希望當 URL 爲 localhost:4200/heroes 時,就導航到 HeroesComponent。
路由器會在瀏覽器的歷史日誌中記錄這個動作,所以前進和後退按鈕也能正常工作。

2.6.2 RouterModule.forRoot()

你必須首先初始化路由器,並讓它開始監聽瀏覽器中的地址變化。
把 RouterModule 添加到 @NgModule.imports 數組中,並用 routes 來配置它。你只要調用 imports 數組中的 RouterModule.forRoot() 函數就行了。

imports: [ RouterModule.forRoot(routes) ],

這個方法之所以叫 forRoot(),是因爲你要在應用的頂級配置這個路由器。 forRoot() 方法會提供路由所需的服務提供商和指令,還會基於瀏覽器的當前 URL 執行首次導航。

2.6.3 路由出口 (RouterOutlet)

<h1>{{title}}</h1>
<router-outlet></router-outlet>
<app-messages></app-messages>  

router-outlet 會告訴路由器要在哪裏顯示路由到的視圖。

2.6.4 路由鏈接 (routerLink)

不應該讓用戶只能把路由的 URL 粘貼到地址欄中。他們還應該能通過點擊鏈接進行導航。
添加一個

<h1>{{title}}</h1>
<nav>
  <a routerLink="/heroes">Heroes</a>
</nav>
<router-outlet></router-outlet>
<app-messages></app-messages> 

routerLink 屬性的值爲 “/heroes”,路由器會用它來匹配出指向 HeroesComponent 的路由。 routerLink 是 RouterLink 指令的選擇器,它會把用戶的點擊轉換爲路由器的導航操作。 它是 RouterModule 中公開的另一個指令。

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