在此頁面中,您將展開Tour of Heroes應用程序以顯示heroes列表,並容許用戶選擇heroes並顯示heroes的詳細信息。css
你須要一些heroes來展現。html
最終你會從遠程數據服務器獲取它們。如今,你會建立一些模擬heroes,並僞裝他們來自服務器。api
建立一個文件夾中調用mock-heroes.ts
的src/app/
文件。定義一個HEROES
由十個heroes組成的數組並將其導出。該文件應該看起來像這樣。數組
//src/app/mock-heroes.ts 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' } ];
6.1-顯示hereos瀏覽器
您即將在頂部顯示heroes列表HeroesComponent
。服務器
打開HeroesComponent
類文件並導入模擬HEROES
。app
src/app/heroes/heroes.component.ts import { HEROES } from '../mock-heroes';
import { Component, OnInit } from '@angular/core'; import { HEROES } from '../mock-heroes'; import { Hero } from '../hero'; @Component({ selector: 'app-heroes', templateUrl: './heroes.component.html', styleUrls: ['./heroes.component.css'] }) export class HeroesComponent implements OnInit { hero: Hero = { id: 1, name: 'Windstorm' }; heroes = HEROES; constructor() { } ngOnInit() { } }
6.2-用 * ngFor列出heroeside
打開HeroesComponent
模板文件並進行如下更改:工具
<h2>
在頂部添加一個,<ul>
)<li>
內<ul>
顯示的屬性hero
。讓它看起來像這樣:ui
<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">
源碼:
<h2>My Heroes</h2> <ul class="heroes"> <li *ngFor="let hero of heroes"> <span class="badge">{{hero.id}}</span> {{hero.name}} </li> </ul>
這*ngFor
是Angular的repeater指令。它重複列表中每一個元素的主機元素。
在這個例子中
<li>
是主機元素heroes
是HeroesComponent
班上的名單。hero
經過列表保存每次迭代的當前heroes對象。不要忘記前面的星號(*)ngFor
。這是語法的關鍵部分。
heroes名單應該是有吸引力的,而且當用戶將鼠標懸停在列表中並從中選擇heroes時,應該以可視方式做出響應。
在第一篇教程中,您將爲整個應用程序設置基本樣式styles.css
。該樣式表不包含這個heroes列表的樣式。
styles.css
在添加組件時,您能夠添加更多樣式並繼續增長樣式表。
您可能更傾向於爲特定組件定義私有樣式,並將組件須要的全部內容(代碼,HTML和CSS)保存在一個地方。
這種方法使得在其餘地方從新使用組件更容易,而且即便全局樣式不一樣,也能夠提供組件的預期外觀。
您能夠在數組中內聯定義私有樣式,也能夠將其定義爲陣列中標識的樣式表文件。@Component.styles
@Component.styleUrls
當CLI生成時HeroesComponent
,它heroes.component.css
爲此建立了一個空的樣式表,HeroesComponent
並像這樣指向它。@Component.styleUrls
// src / app / heroes / heroes.component.ts(@Component) @Component({ selector: 'app-heroes', templateUrl: './heroes.component.html', styleUrls: ['./heroes.component.css'] })
打開該heroes.component.css
文件並粘貼私人CSS樣式HeroesComponent
。您能夠在本指南底部的最終代碼審查中找到它們。
元數據中標識的樣式和樣式表被限定爲特定組件。這些樣式僅適用於和不影響任何其餘組件中的外部HTML或HTML。
@Component
heroes.component.css
HeroesComponent
當用戶點擊主列表中的heroes時,該組件應該在頁面底部顯示所選heroes的詳細信息。
在本節中,您將聽取heroes項目點擊事件並更新heroes細節。
添加一個點擊事件綁定到<li>
這樣的:
<li *ngFor="let hero of heroes" (click)="onSelect(hero)">
這是Angular的事件綁定語法的一個例子。
周圍的圓括號click
告訴Angular傾聽<li>
元素的 click
事件。當用戶點擊時<li>
,Angular執行onSelect(hero)
表達式。
onSelect()
是HeroesComponent
你即將寫的一種方法。Angular用hero
點擊顯示的對象進行調用,與以前在表達式中定義<li>
的相同。hero
*ngFor
重命名組件的hero
屬性,selectedHero
但不分配它。應用程序啓動時沒有選定的heroes。
添加如下onSelect()
方法,該方法將模板中單擊的heroes分配給組件selectedHero
。
// src / app / heroes / heroes.component.ts(onSelect) selectedHero: Hero; onSelect(hero: Hero): void { this.selectedHero = hero; }
模板仍然引用hero
再也不存在的組件的舊屬性。重命名hero
爲selectedHero
。
//heroes.component.html <h2>{{ selectedHero.name | uppercase }} Details</h2> <div><span>id: </span>{{selectedHero.id}}</div> <div> <label>name: <input [(ngModel)]="selectedHero.name" placeholder="name"> </label> </div>
瀏覽器刷新後,應用程序被破壞。
打開瀏覽器開發人員工具,而後在控制檯中查找像這樣的錯誤消息:
如今點擊其中一個列表項。該應用程序彷佛再次工做。heroes出如今列表中,而且關於被點擊的heroes的詳細信息出如今頁面的底部。
當應用程序啓動時,這selectedHero
是undefined
設計。
在模板中引用selectedHero
像{{selectedHero.name}}
- 這樣的表達式的屬性的綁定表達式必須失敗,由於沒有選定的heroes。
若是selectedHero
存在,組件應該只顯示選定的heroes細節。
將heroes細節HTML包裝在一個<div>
。將Angular的指令添加到並設置爲。*ngIf
<div>
selectedHero
不要忘記前面的星號(*)ngIf
。這是語法的關鍵部分。
src / app / heroes / heroes.component.html(* ngIf)
<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>
瀏覽器刷新後,名稱列表從新出現。詳細信息區域爲空白。點擊一個heroes並顯示其詳細信息。
什麼時候selectedHero
未定義,ngIf
從DOM中刪除heroes細節。沒有selectedHero
綁定擔憂。
當用戶選擇heroes時,selectedHero
有一個值 ngIf
並將heroes詳細信息放入DOM中。
當全部元素看起來類似時,很難在列表中識別選定的heroes<li>
。
若是用戶點擊「Magneta」,那麼這個heroes應該用一個獨特但微妙的背景顏色渲染,以下所示:
這個選定的heroes着色是你在前面添加.selected
的樣式中的CSS類的工做。您只需將該.selected
類應用到<li>
用戶點擊該類時。
Angular 類的綁定能夠很容易地有條件地添加和刪除一個CSS類。只需添加[class.some-css-class]="some-condition"
到你想要的樣式。
下面添加[class.selected]
綁定到<li>
的HeroesComponent
模板:
heroes.component.html(切換'所選'CSS類)
[class.selected]="hero === selectedHero"
當前行的heroes是相同的selectedHero
,Angular添加了selected
CSS類。當兩位heroes不同時,Angular會刪除這個班級。
完成<li>
看起來像這樣:
<li *ngFor="let hero of heroes" [class.selected]="hero === selectedHero" (click)="onSelect(hero)"> <span class="badge">{{hero.id}}</span> {{hero.name}} </li>
最終源碼:
//heroes.component.ts <h2>My Heroes</h2> <ul class="heroes"> <li *ngFor="let hero of heroes"
//選擇所選類 [class.selected]="hero === selectedHero"
//添加單擊事件 (click)="onSelect(hero)"> <span class="badge">{{hero.id}}</span> {{hero.name}} </li> </ul> <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>
/* HeroesComponent's private CSS styles */ .selected { background-color: #CFD8DC !important; color: white; } .heroes { margin: 0 0 2em 0; list-style-type: none; padding: 0; width: 15em; } .heroes li { cursor: pointer; position: relative; left: 0; background-color: #EEE; margin: .5em; padding: .3em 0; height: 1.6em; border-radius: 4px; } .heroes li.selected:hover { background-color: #BBD8DC !important; color: white; } .heroes li:hover { color: #607D8B; background-color: #DDD; left: .1em; } .heroes .text { position: relative; top: -3px; } .heroes .badge { display: inline-block; font-size: small; color: white; padding: 0.8em 0.7em 0 0.7em; background-color: #607D8B; line-height: 1em; position: relative; left: -1px; top: -4px; height: 1.8em; margin-right: .8em; border-radius: 4px 0 0 4px; }
//heroes.component.ts
import { Component, OnInit } from '@angular/core'; import { Hero } from '../hero'; import { HEROES } from '../mock-heroes'; @Component({ selector: 'app-heroes', templateUrl: './heroes.component.html', styleUrls: ['./heroes.component.css'] }) export class HeroesComponent implements OnInit { heroes = HEROES; selectedHero: Hero; constructor() { } ngOnInit() { } onSelect(hero: Hero): void { this.selectedHero = hero; } }