在本頁面,你將擴展《英雄指南》應用,讓它顯示一個英雄列表, 並容許用戶選擇一個英雄,查看該英雄的詳細信息。css
你須要一些英雄數據以供顯示。html
最終,你會從遠端的數據服務器獲取它。可是目前,你須要建立一些模擬英雄(some mock heroes),並假設這些數據是從遠程服務器上獲取的。git
在 src/app/
文件夾中建立一個名叫 mock-heroes.ts
的文件。 定義一個包含十個英雄的常量數組 HEROES
,並導出它。 該文件是這樣的。github
src/app/mock-heroes.tsapi
|
你要在 HeroesComponent
的頂部顯示這個英雄列表。
打開 HeroesComponent
類文件,並導入模擬的 HEROES 數據。
src/app/heroes/heroes.component.ts
|
往類中添加一個 heroes
屬性,這樣能夠暴露出這些英雄,以供綁定。
src/app/heroes/heroes.component.ts
|
*
ngFor 列出這些英雄打開 HeroesComponent
的模板文件,並作以下修改:
<h2>
<ul>
)<ul>
中插入一個 <li>
元素,以顯示單個 hero
的屬性。完成後應該以下顯示:
heroes.component.html
|
如今,把 <li>
修改爲這樣:
|
*ngFor
是一個 Angular 的複寫器(repeater)指令。 它會爲列表中的每項數據複寫它的宿主元素。
在這個例子中
<li>
就是 *
ngFor 的宿主元素heroes
就是來自 HeroesComponent
類的列表。hero
會爲每一個迭代保存當前的英雄對象。不要忘了 ngFor 前面的星號(*
),它是該語法中的關鍵部分。
瀏覽器刷新以後,英雄列表出現了。
英雄列表應該富有吸引力,而且當用戶把鼠標移到某個英雄上和從列表中選中某個英雄時,應該給出視覺反饋。
在教程的第一章,你曾在 styles.css
中爲整個應用設置了一些基礎的樣式。 但那個樣式表並不包含英雄列表所需的樣式。
當然,你能夠把更多樣式加入到 styles.css
,而且聽任它隨着你添加更多組件而不斷膨脹。
但還有更好的方式。你能夠定義屬於特定組件的私有樣式,而且讓組件所需的一切(代碼、HTML 和 CSS)都放在一塊兒。
這種方式讓你在其它地方複用該組件更加容易,而且即便全局樣式和這裏不同,組件也仍然具備指望的外觀。
你能夠用多種方式定義私有樣式,或者內聯在 @
Component.styles 數組中,或者在 @
Component.styleUrls 所指出的樣式表文件中。
當 CLI 生成 HeroesComponent
時,它也同時爲 HeroesComponent
建立了空白的 heroes.component.css
樣式表文件,而且讓 @
Component.styleUrls 指向它,就像這樣:
src/app/heroes/heroes.component.ts
|
打開 heroes.component.css
文件,而且把 HeroesComponent
的私有 CSS 樣式粘貼進去。 你能夠在本指南底部的查看最終代碼中找到它們。
@
Component 元數據中指定的樣式和樣式表都是侷限於該組件的。 heroes.component.css
中的樣式只會做用於 HeroesComponent
,既不會影響到組件外的 HTML,也不會影響到其它組件中的 HTML。
當用戶在主列表中點擊一個英雄時,該組件應該在頁面底部顯示所選英雄的詳情。
在本節,你將監聽英雄條目的點擊事件,並更新英雄的詳情。
click
事件綁定再往 <li>
元素上插入一句點擊事件的綁定代碼:
heroes.component.html
|
這是 Angular 事件綁定 語法的例子。
click
外面的圓括號會讓 Angular 監聽這個 <li>
元素的 click
事件。 當用戶點擊 <li>
時,Angular 就會執行表達式 onSelect(hero)
。
onSelect()
是 HeroesComponent
上的一個方法,你很快就要寫它。 Angular 會把所點擊的 <li>
上的 hero
對象傳給它,這個 hero
也就是前面在 *
ngFor 表達式中定義的那個。
click
事件處理器把該組件的 hero
屬性更名爲 selectedHero
,但不要爲它賦值。 由於應用剛剛啓動時並無所選英雄。
添加以下 onSelect()
方法,它會把模板中被點擊的英雄賦值給組件的 selectedHero
屬性。
src/app/heroes/heroes.component.ts
|
該模板引用的仍然是老的 hero
屬性,但它已經不存在了。 把 hero
更名爲 selectedHero
。
heroes.component.html
|
刷新瀏覽器,應用掛了。
打開瀏覽器的開發者工具,它的控制檯中顯示出以下錯誤信息:
|
當應用啓動時,selectedHero
是 undefined
,設計如此。
但模板中的綁定表達式引用了 selectedHero
的屬性(表達式爲 {{
selectedHero.name}}
),這必然會失敗,由於你還沒選過英雄呢。
如今,從列表中隨便點擊一個條目。 應用又正常了。 英雄們顯示在列表中,而且所點英雄的詳情也顯示在了頁面的下方。
該組件應該只有當 selectedHero
存在時才顯示所選英雄的詳情。
把顯示英雄詳情的 HTML 包裹在一個 <div>
中。 而且爲這個 div 添加 Angular 的 *
ngIf 指令,把它的值設置爲 selectedHero
。
不要忘了 ngIf 前面的星號(*
),它是該語法中的關鍵部分。
src/app/heroes/heroes.component.html (*ngIf)
|
瀏覽器刷新以後,英雄名字的列表又出現了。 詳情部分仍然是空。 點擊一個英雄,它的詳情就出現了。 這個應用看起來又再次工做正常顯示了。 英雄顯示在列表中,當你單擊英雄的名字的時候,有關你單擊英雄的詳細信息就顯示在頁面的底部了。
當 selectedHero
爲 undefined
時,ngIf 從 DOM 中移除了英雄詳情。所以也就不用擔憂 selectedHero
的綁定了。
當用戶選擇一個英雄時,selectedHero
也就有了值,而且 ngIf 把英雄的詳情放回到 DOM 中。
全部的 <li>
元素看起來都是同樣的,所以很難從列表中識別出所選英雄。
若是用戶點擊了「Magneta」,這個英雄應該用一個略有不一樣的背景色顯示出來,就像這樣:
所選英雄的顏色來自於你前面添加的樣式中的 CSS 類 .selected
。 因此你只要在用戶點擊一個 <li>
時把 .selected
類應用到該元素上就能夠了。
Angular 的 CSS 類綁定機制讓根據條件添加或移除一個 CSS 類變得很容易。 只要把 [class.some-css-class]="some-condition"
添加到你要施加樣式的元素上就能夠了。
在 HeroesComponent
模板中的 <li>
元素上添加 [class.selected]
綁定,代碼以下:
heroes.component.html (toggle the 'selected' CSS class)
|
若是當前行的英雄和 selectedHero
相同,Angular 就會添加 CSS 類 selected
,不然就會移除它。
最終的 <li>
是這樣的:
heroes.component.html (list item hero)
|
下面是本頁面中所說起的代碼文件,包括 HeroesComponent
的樣式。
對應的文件列表和代碼連接以下:
文件名 |
源代碼 |
---|---|
src/app/heroes/heroes.component.ts | https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-list/blob/master/src/app/heroes/heroes.component.ts |
src/app/heroes/heroes.component.html | https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-list/blob/master/src/app/heroes/heroes.component.html |
src/app/heroes/heroes.component.css | https://github.com/cwiki-us-angular/cwiki-us-angular-tour-of-heroes-list/blob/master/src/app/heroes/heroes.component.css |
*
ngFor 顯示了一個列表。*
ngIf 來根據條件包含或排除了一段 HTML。class
綁定來切換 CSS 的樣式類。https://www.cwiki.us/display/AngularZH/Display+a+Heroes+List