天天看點

Angular項目的建立及案例解釋

   初學angular 其實前端的難度本身不大  但是一些架構在自主了解上還是有一些不好了解的 是以如果可以多向别人請教一下 或者自行百度搜尋 畢竟每個人的了解程度不同 

          建議檢視有道雲筆記的連結   有些格式和圖檔不能同步

http://note.youdao.com/noteshareid=cbe3907fea4268015d879ba5c463147d&sub=B2932DAF36BC445789D3D31D051C9AE2

1. 建立準備項目工作

利用cmd建立項目基礎工作

每一個工作空間都包含有一些供一個或多個項目使用的檔案 每個項目都是由 應用~庫或端~端(e2e)測試構成的檔案

安裝angular-cli ng new my-app

還将建立下列工作空間和初始項目檔案:

  • 一個新的工作空間,根目錄名叫 my-app
  • 一個初始的骨架應用項目,也叫 my-app(但位于 src 子目錄下)
  • 一個端到端測試項目(位于 e2e 子目錄下)
  • 相關的配置檔案

第一個案例 實作了在component.ts 中 給title屬性傳值 又在component.css裡面進行樣式渲染

2. 建立英雄清單元件

使用指令 ng generate component heroes 建立完成後出現相應的三個檔案

類檔案 ts 頁面進來導入 Component(裝飾器函數 用于提供所需原資料) OnInit(鈎子函數)

CLI 自動生成了三個中繼資料屬性:

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

ngoninit 是一個生命周期鈎子函數(回調函數) 在建立完元件之後很快就會調用ngOnInit,這裡是放置初始化邏輯的地方

添加 HeroesComponent 中的一個屬性 表示一個英雄 hero = ‘Windstorm’;

然後在 模闆檔案中使用{{}} 顯示出來

3. 顯示建立heros元件

想要去顯示就必須把它加在殼元件 AppComponent的模闆中

app-heros 就是HerosComponent 的元素選擇器 是以要把 <app-heroes></app-heroes> 添加到APPComponent的模闆檔案中就可以

4. 運作 使用 指令行 ng serve --open 這樣就會自動去運作出來 ctrl + s 也會自動重新整理

5. 再去建立一個 Hero 類 去模拟更多的資料

在 src/app 下面 建立 hero.ts 并且添加 id和name 屬性

export class Hero {

id: number;

name: string;

}

回到heroes的 類檔案中 去引入這個類 去進行傳值 把原來的 hero=“變量内容” 替換為

hero:Hero = {

id:1,

name:"WindStorm"

}

這樣會出現顯示錯誤 因為這是一個對象 我們可以使用 hero.id .name 進行顯示 同時還可以進行格式化 <h2>{{hero.name | uppercase}} Details</h2> name值就變成了大寫 有很多管道 黑可以自己建立

6. 英雄的名字改為可編輯 就得需要用到輸入框 能夠同時進行顯示和修改英雄的name屬性 資料流從 元件類流出到螢幕,再從螢幕回到螢幕的元件類 要在表單元素<input>群組件的 hero.name 屬性之 間建立雙向的資料綁定

<div>

<label>name:

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

</label>

</div>

[(ngModel)] 是 Angular 的雙向資料綁定文法。

這裡把 hero.name 屬性綁定到了 HTML 的 textbox 元素上,以便資料流可以雙向流動:從 hero.name 屬性流動到 textbox,并且從 textbox 流回到 hero.name 。

但是不能夠顯示了 因為 ngModel 在預設情況下是不可用的 要自己進行添加

但是實際測試是可以的 可能是因為官網沒有更新

小結:

你使用 CLI 建立了第二個元件 HeroesComponent。

  • 你把 HeroesComponent 添加到了殼元件 AppComponent 中,以便顯示它。
  • 你使用 UppercasePipe 來格式化英雄的名字。
  • 你用 ngModel 指令實作了雙向資料綁定。
  • 你知道了 AppModule。
  • 你把 FormsModule 導入了 AppModule,以便 Angular 能識别并應用 ngModel 指令。
  • 你知道了把元件聲明到 AppModule 是很重要的,并認識到 CLI 會自動幫你聲明它。

7 . 顯示一個英雄資料清單(還是建立一些模拟資料) 就是利用for 進行展示

建立一個 mock-heroes.ts 檔案 包含是十個常量數組 HEROES

這個類其實一開始還是進行了引入 隻是把格式進行了傳值

import { Hero } from './hero';

export const HEROES: Hero[] = [

{ id: 11, name: 'Mr. Nice' },

{ id: 12, name: 'Narco' },

{ id: 13, name: 'Bombasto' },

{ id: 14, name: 'Celeritas' },

{ id: 15, name: 'Magneta' },

{ id: 16, name: 'RubberMan' },

{ id: 17, name: 'Dynama' },

{ id: 18, name: 'Dr IQ' },

{ id: 19, name: 'Magma' },

{ id: 20, name: 'Tornado' }

];

在 heroes.component 裡面進行引入HEROES 然後聲明屬性進行指派 heroes = HEROES;

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

*ngFor 是一個 Angular 的複寫器(repeater)指令。 它會為清單中的每項資料複寫它的宿主元素。

在這個例子中

<li> 就是 *ngFor 的宿主元素

heroes 就是來自 HeroesComponent 類的清單。

當依次周遊這個清單時,hero 會為每個疊代儲存目前的英雄對象。

8. 進行相關的css樣式綁定

你曾在 styles.css 中為整個應用設定了一些基礎的樣式。 但那個樣式表并不包含英雄清單所需的樣式。固然,你可以把更多樣式加入到 styles.css,并且放任它随着你添加更多元件而不斷膨脹。但還有更好的方式。你可以定義屬于特定元件的私有樣式,并且讓元件所需的一切(代碼、HTML 和 CSS)都放在一起。這種方式讓你在其它地方複用該元件更加容易,并且即使全局樣式和這裡不一樣,元件也仍然具有期望的外觀。你可以用多種方式定義私有樣式,或者内聯在 @Component.styles 數組中,或者在 @Component.styleUrls 所指出的樣式表檔案中。

@Component 中繼資料中指定的樣式和樣式表都是局限于該元件的。 heroes.component.css 中的樣式隻會作用于 HeroesComponent,既不會影響到元件外的 HTML,也不會影響到其它元件中的 HTML。

9 。 主從結構 進行相關的監聽英雄條目的點選事件 并且更新英雄的詳情

<li *ngFor="let hero of heroes" (click)="onSelect(hero)"> //這是格式

click 外面的圓括号會讓Angular 監聽這個<li> 元素的click事件 當使用者點選<li>時 就會執行表達式 onSelect(hero) 并且onSelect() 是HeroComponent 上的一個方法

添加如下 onSelect() 方法,它會把模闆中被點選的英雄指派給元件的 selectedHero 屬性。

selectedHero: Hero;

onSelect(hero: Hero): void { 這句就是傳進來的英雄詳情

this.selectedHero = hero;

}

重點: 我不明白是因為我笨還是啥 我這個地方想了好久

原來的時候這地方是資料綁定 現在他把原來的傳值指派 給不用了 你這麼想他是想做一個詳情的東西 你點選她把點選的資料英雄給你 然後你就要把資料附上去 付給那個格式 這樣你點選哪一個就是把那個模闆改了進行傳值 然後進行顯示

還有就是一開始 selectedHero 傳的值就是引入進來的Hero 是空的 是以詳情是沒辦法顯示的 是以上來要先判斷否為空 用到 *ngIf="selectedHero" 他會幫你一處

格式 外面包裹 <div *ngIf="selectedHero">

綁定點選之後的樣式 意思就是點選了之後 給他添加一個css名

Angular 的 CSS 類綁定機制讓根據條件添加或移除一個 CSS 類變得很容易。 隻要把 [class.some-css-class]="some-condition" 添加到你要施加樣式的元素上就可以了。

[class.selected]="hero === selectedHero" 所在點選的 <li>

10. 主從元件 意義就是能夠把多次複用的元件進行拆開多次利用 忽然想到在在寫多個頁面的時候,我們就把每個頁面都寫成一個元件有自己的配置檔案 然後呢 你把每個頁頭當作一個元件,進行複用 這樣就是一個網站的大體想法 暫時先這麼了解 後面想到更全面的再來補充

官網上邊說 把所有特性都房子啊同一個元件中 将會使應用“長大:後不可維護 你要把大型元件拆分成小一點的子元件 每個元件都要集中精力處理某個特定的任務或工作流

這節就是拆分英雄詳情 制作HeroDetailComponent

利用 CLI 生成 hero-detail的元件

首先 把原來元件中的HTML英雄詳情 剪切 粘貼

官網說 要把selectedHero 替換成 hero 這樣的話 就是不隻是顯示點選英雄的詳情 都要顯示

是以用到一個 @Input() hero 屬性 Input需要在本元件中進行 導入因為他是angular的屬性

@Input() hero: Hero;

顯示元件 HeroDetailComponent

你想 HerosComponent 是主元件是父元件 要在它裡面顯示詳情是以 你不用修改他的類檔案 但是要修改他的模闆檔案 HeroDetailComponent 的選擇器是 <app-hero-detail> 是以就是

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

[hero]="selectedHero" 是 Angular 的屬性綁定文法。 這是單向資料綁定 從 HeroesComponent 的 selectedHero 屬性綁定到目标元素的 hero 屬性,并映射到了 HeroDetailComponent 的 hero 屬性。現在,當使用者在清單中點選某個英雄時,selectedHero 就改變了。 當 selectedHero 改變時,屬性綁定會修改 HeroDetailComponent 的 hero 屬性,HeroDetailComponent 就會顯示這個新的英雄。

類似于點選事件 隻不過傳參變成了屬性綁定 這樣就可以 進行元件之間的互相通信 然後互相的資料顯示

小總結 感覺還可以

11. 服務 截止到目前 還都是模拟資料

官網說 服務會了之後 HeroComponent 變得更加精簡 并且聚焦于為它的視圖提供支援 這也讓它更加 容易模拟服務進行單元測試

官網還說了 組價不應該直接擷取或者儲存資料 他們不應該了解是否展示的是假的資料 他們應該聚焦于展示資料 而把資料通路的職責委托給某個服務

我說 我知道 哈哈 Android就是這樣 因為人家還有5各元件來 其實無非就是站在大的角度上看着 你做你的 我做我的 我們之間互相來往 減少不必要的損耗 減少代碼備援

官網又說了 你要建立一個HeroService 應用中的所用的類都可以找他來擷取英雄清單 不要用new來建立此服務 而要依靠Angular的 依賴注入機制(我靠 這個我一直沒懂)把它注入到HeroesComponent的構造函數裡面

官網我覺得你要閉嘴--------上圖

建立 服務 ng generate service hero

他可以從任何地方擷取資料 web服務 本地存儲 或 一個模拟的資料源

OK 出現 hero.service.ts @Injectable() 服務 (說真的我到這真的沒懂)

提供(provide) HeroService (還是沒懂)

當你在頂層提供服務時 angular就會為 HeroService 建立一個單一的,共享的執行個體,并把它注入到任何想要他的類上 在@Injectable 中繼資料中注冊過提供商 還能讓Angular 可以通過移除那些完全沒有用過的服務 來進行優化

實作步驟

1 操作 修改 HeroesComponent 不要HEROES 了 要 HeroService(說的是導包)、

2在 服務的代碼裡面 寫一個 getHeroes(): Hero[] {return HEROES;} 模拟傳回資料

3在跟元件裡面 的 構造函數裡面 進行 constructor(private heroService: HeroService) { }

這個參數同時做了兩件事:1. 聲明了一個私有 heroService 屬性,2. 把它标記為一個 HeroService 的注入點。當 Angular 建立 HeroesComponent 時,依賴注入系統就會把這個 heroService 參數設定為 HeroService 的單例對象。

4. 建立一函數 從服務裡面去接收值

getHeroes(): void {

this.heroes = this.heroService.getHeroes();

}

5. 調用這個函數 他會把 heroes的值改成對象傳回過來的

6 。 在 ngOnInit(){ } 進行調用 這是生命周期鈎子函數 他會在構造出HeroesComponent 的執行個體之後的某個合适的時機調用

個人了解: 這個案例的意思就是 把原來的 HEROES 的資料改為 服務去擷取在服務裡面去寫一個方法然後傳回 HEROES 的資料 然後在 主元件裡面 的構造函數裡面 聲明一個私有化類型為 HeroService 其實就是在建立一個服務類的對象 然後通過對象去拿數值 注意angular6 才會有Injection root 如果不是 那就在APP module裡面聲明那個服務類

12 . 可觀察(Observable) 的資料 (我不知道這是什麼東西)

Observable 是 RxJS庫 中的一個關鍵類 Angular HttpClient 的方法會傳回 RxJS 的 Observable。 使用 RxJS 的 of() 函數來模拟從伺服器傳回資料。

說白了其實在上面的擷取模拟資料裡面是不對的 請求資料是異步加載 要不然你拿不到啊 是以前端必須用 RxJS

這個案例 就是 建立一個元件 進行服務的嵌套 模拟伺服器端的資料 是以暫時不看了 等有空再看 直接去HTTP 下一節路由

13. 路由

添加 APPRoutingModule Angular的最佳實踐就是在一個獨立頂尖子產品中加載和配置路由器 他專注于路由功能 然後由根子產品 AppModule 導入他

ng generate module app-routing --flat --module=app

--flat 把這個檔案放進了 src/app 中,而不是單獨的目錄中。

--module=app 告訴 CLI 把它注冊到 AppModule 的 imports 數組中。

一般不會在路由子產品中聲明元件 是以可以删除@NgModule.declarations 并删除對CommonModule的引用 會使用RouterModule 中的Routers類來配置路由器 是以還要從 @angular/router 庫中導入這兩個符号。添加一個 @NgModule.exports 數組,其中放上 RouterModule 。 導出 RouterModule 讓路由器的相關指令可以在 AppModule 中的元件中使用。(其實就是需要一個固有的配置)

路由定義 會告訴路由器 當使用者點選某個連結或者在浏覽器的位址欄輸入某個URL時 要顯示哪個視圖

典型的Angular 路由(router)有兩個屬性:

1. path : 一個用于比對浏覽器位址欄中的URL的字元串

2.component: 當導航到此路由時 路由器應該建立哪個元件

例如 such as (就會這一個單詞了)

如果你希望當URL為 localhost:4200/heros 時 就導航到Heroescomponent

首先要導入 HeroesComponent 以便于在Router中引用他 然後定義一個路由數組 其中某個路由是指向這個元件的 例如 上圖

完成這些設定後 路由器将會把URL 比對到 path:'heroes ' 并顯示 HeroesComponent元件

RouterModule。forRoot()

你必須要先初始化路由器 并讓他開始監聽浏覽器中的位址變化

把 RouterModule 添加到 @NgModule.imports 數組中,并用 routes 來配置它。你隻要調用 imports 數組中的 RouterModule.forRoot() 函數就行了。

添加路由出口(RouterOutlet)

把原來的模闆的<app-heroes>替換成<router-outlet> 之是以會替換 說是因為隻有使用者導航到這裡時 才需要顯示 HeroesComponent 但是<router-outlet>會告訴路由器要在哪裡顯示路由到的視圖

在APPcomponent的模闆檔案裡面 寫一個nav 包含a 屬性 routerLink=“/heros” 這樣就可以進行跳轉

繼續

添加儀表盤視圖 路由隻有在視圖的時候 才管用

是以 添加一個元件 就是儀表盤的元件 ng generate component dashboard

這個儀表盤裡面就隻有4個英雄 隻是為了顯示 利用的是 HeroService的資料進行截取

getHeroes(): void {

this.heroService.getHeroes()

.subscribe(heroes => this.heroes = heroes.slice(1, 5));

}

然後使用 *ngFor 進行相應的循環輸出

然後進行儀表盤的路由添加 導包 和 path

再然後 我們需要進行 預設路由的添加 你想 在APPcomponent 的HTML裡面 就隻有兩個按鈕隻有你點了才會出現下面的内容 是以我們希望是先要顯示儀表盤裡的Dashboard

{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },

這個路由會把一個與空路徑“完全比對”的 URL 重定向到路徑為 '/dashboard' 的路由。

現在你就可以看見 顯示出現 四個英雄的相關元件 上面有兩個超連結

導航到英雄的詳情 1 我們需要在那四個的頁面可以進行點選進入詳情

2 我們需要在英雄清單裡面進行點選去進入詳情

3 在位址欄裡面進行相應的位址粘貼去顯示英雄

删除在HeroesComponent裡面的英雄詳情

思路

那我們應該怎麼想呢 其實 路由的作用就是 切換相應的視圖顯示與不顯示 在那個主要的APPcomponent模闆檔案裡面 有一個路由入口 然後還有兩個顯示誰的超連結 這樣的話 我們就進行切換的顯示 在那個顯示的詳情 首先你要有點選事件就是跳轉的連接配接也可以 那麼重點就是誰點選的是以我們把原來點選的連接配接 routerLink=“./ashboard/{{hero.id}}" 寫在這個位置同時這個不是用的ngFor嗎,那就可以進行相應的本元素資料擷取heroid 就是真麼來的 , 就是給他們用循環進行添加這個 然後我們在 詳情裡面有方法擷取URL 然後ID的區分擷取相應的顯示資料

具體實作: 我們去看官網吧 他的那個詳情圖的顯示使用了很多的方法 我不明白 是以我就不想寫了用到在看 但是套路得知道 要不然及時沒懂

14. HTTP

到時候回來重新寫 因為官網的案例比較亂 而且有很多沒用的東西 是以需要重新進行操作重新記錄

實作要求

1.HeroService通過HTTP 請求擷取英雄資料

2.可以添加,編輯,删除 儲存HTTP的更改

3. 可以根據名字搜尋英雄

啟用 HTTP 服務

打開根子產品 AppModule,

從 @angular/common/http 中導入 HttpClientModule 符号,

15.架構模式

Angular 是一個HTML 和 TS 建構用戶端 應用的平台與架構

5. 調用這個函數 他會把 heroes的值改成對象傳回過來的

6 。 在 ngOnInit(){ } 進行調用 這是生命周期鈎子函數 他會在構造出HeroesComponent 的執行個體之後的某個合适的時機調用

個人了解: 這個案例的意思就是 把原來的 HEROES 的資料改為 服務去擷取在服務裡面去寫一個方法然後傳回 HEROES 的資料 然後在 主元件裡面 的構造函數裡面 聲明一個私有化類型為 HeroService 其實就是在建立一個服務類的對象 然後通過對象去拿數值 注意angular6 才會有Injection root 如果不是 那就在APP module裡面聲明那個服務類

12 . 可觀察(Observable) 的資料 (我不知道這是什麼東西)

Observable 是 RxJS庫 中的一個關鍵類 Angular HttpClient 的方法會傳回 RxJS 的 Observable。 使用 RxJS 的 of() 函數來模拟從伺服器傳回資料。

說白了其實在上面的擷取模拟資料裡面是不對的 請求資料是異步加載 要不然你拿不到啊 是以前端必須用 RxJS

這個案例 就是 建立一個元件 進行服務的嵌套 模拟伺服器端的資料 是以暫時不看了 等有空再看 直接去HTTP 下一節路由

13. 路由

添加 APPRoutingModule Angular的最佳實踐就是在一個獨立頂尖子產品中加載和配置路由器 他專注于路由功能 然後由根子產品 AppModule 導入他

ng generate module app-routing --flat --module=app

--flat 把這個檔案放進了 src/app 中,而不是單獨的目錄中。

--module=app 告訴 CLI 把它注冊到 AppModule 的 imports 數組中。

一般不會在路由子產品中聲明元件 是以可以删除@NgModule.declarations 并删除對CommonModule的引用 會使用RouterModule 中的Routers類來配置路由器 是以還要從 @angular/router 庫中導入這兩個符号。添加一個 @NgModule.exports 數組,其中放上 RouterModule 。 導出 RouterModule 讓路由器的相關指令可以在 AppModule 中的元件中使用。(其實就是需要一個固有的配置)

路由定義 會告訴路由器 當使用者點選某個連結或者在浏覽器的位址欄輸入某個URL時 要顯示哪個視圖

典型的Angular 路由(router)有兩個屬性:

1. path : 一個用于比對浏覽器位址欄中的URL的字元串

2.component: 當導航到此路由時 路由器應該建立哪個元件

例如 such as (就會這一個單詞了)

如果你希望當URL為 localhost:4200/heros 時 就導航到Heroescomponent

首先要導入 HeroesComponent 以便于在Router中引用他 然後定義一個路由數組 其中某個路由是指向這個元件的 例如 上圖

完成這些設定後 路由器将會把URL 比對到 path:'heroes ' 并顯示 HeroesComponent元件

RouterModule。forRoot()

你必須要先初始化路由器 并讓他開始監聽浏覽器中的位址變化

把 RouterModule 添加到 @NgModule.imports 數組中,并用 routes 來配置它。你隻要調用 imports 數組中的 RouterModule.forRoot() 函數就行了。

添加路由出口(RouterOutlet)

把原來的模闆的<app-heroes>替換成<router-outlet> 之是以會替換 說是因為隻有使用者導航到這裡時 才需要顯示 HeroesComponent 但是<router-outlet>會告訴路由器要在哪裡顯示路由到的視圖

在APPcomponent的模闆檔案裡面 寫一個nav 包含a 屬性 routerLink=“/heros” 這樣就可以進行跳轉

繼續

添加儀表盤視圖 路由隻有在視圖的時候 才管用

是以 添加一個元件 就是儀表盤的元件 ng generate component dashboard

這個儀表盤裡面就隻有4個英雄 隻是為了顯示 利用的是 HeroService的資料進行截取

getHeroes(): void {

this.heroService.getHeroes()

.subscribe(heroes => this.heroes = heroes.slice(1, 5));

}

然後使用 *ngFor 進行相應的循環輸出

然後進行儀表盤的路由添加 導包 和 path

再然後 我們需要進行 預設路由的添加 你想 在APPcomponent 的HTML裡面 就隻有兩個按鈕隻有你點了才會出現下面的内容 是以我們希望是先要顯示儀表盤裡的Dashboard

{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },

這個路由會把一個與空路徑“完全比對”的 URL 重定向到路徑為 '/dashboard' 的路由。

現在你就可以看見 顯示出現 四個英雄的相關元件 上面有兩個超連結

導航到英雄的詳情 1 我們需要在那四個的頁面可以進行點選進入詳情

2 我們需要在英雄清單裡面進行點選去進入詳情

3 在位址欄裡面進行相應的位址粘貼去顯示英雄

删除在HeroesComponent裡面的英雄詳情

思路

那我們應該怎麼想呢 其實 路由的作用就是 切換相應的視圖顯示與不顯示 在那個主要的APPcomponent模闆檔案裡面 有一個路由入口 然後還有兩個顯示誰的超連結 這樣的話 我們就進行切換的顯示 在那個顯示的詳情 首先你要有點選事件就是跳轉的連接配接也可以 那麼重點就是誰點選的是以我們把原來點選的連接配接 routerLink=“./ashboard/{{hero.id}}" 寫在這個位置同時這個不是用的ngFor嗎,那就可以進行相應的本元素資料擷取heroid 就是真麼來的 , 就是給他們用循環進行添加這個 然後我們在 詳情裡面有方法擷取URL 然後ID的區分擷取相應的顯示資料

具體實作: 我們去看官網吧 他的那個詳情圖的顯示使用了很多的方法 我不明白 是以我就不想寫了用到在看 但是套路得知道 要不然及時沒懂

14. HTTP

到時候回來重新寫 因為官網的案例比較亂 而且有很多沒用的東西 是以需要重新進行操作重新記錄

實作要求

1.HeroService通過HTTP 請求擷取英雄資料

2.可以添加,編輯,删除 儲存HTTP的更改

3. 可以根據名字搜尋英雄

啟用 HTTP 服務

打開根子產品 AppModule,

從 @angular/common/http 中導入 HttpClientModule 符号,

15.架構模式

Angular 是一個HTML 和 TS 建構用戶端 應用的平台與架構