[Angular2官方tutorial學習02]display list,master detail,click event,master detail advanced,幫css設定加上if
@接下來要練習在畫面上顯示一個list,類似查詢出來一堆資料這樣。
@首先要先做一些假資料,所以請先新增一個檔案src/app/mock-heroes.ts,檔案內容如下
import Hero這個這個class之後,就可以直接宣告一些假資料了,用json的form做資料即可。如此一來在server端就已經建立好假資料了
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' }
];
@然後我們希望在HerosComponet顯示這個清單,所以接著在src/app/heroes/heroes.component.ts加入下列import,把剛才的假資料import進來
import { HEROES } from '../mock-heroes';
然後再於同一檔案內的export class HeroesComponent implements OnInit裡面新增一個property叫做heros,用來讀取剛才的假資料
heroes = HEROES;
最後看起來會是這樣
再來於src\app\heroes\heroes.component.html加入下列內容,用來顯示假資料的清單
*ngFor就是angular的迴圈語法,let就是宣告區域變數(注意別用var宣告變數,會變成全域變數)
<h2>My Heroes</h2>
<ul class="heroes">
<li *ngFor="let hero of heroes">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
最後看起來會像是這樣
打開網頁瀏覽器,此時畫面已經成功顯示剛才的假資料了,雖然畫面有點醜,但是這不重要先不理會囉
最後於src\app\heroes\heroes.component.css輸入官方提供的css排版語法,這些語法因為寫在heroes.component.css檔案裡,因此不會影響到其他的component,是不是很方便呢?
/* 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;
}
這樣子排版之後,網頁瀏覽器的結果看起來會好一點……嗎 XD
@接著要示範master detail的畫面設計以及click event
請把於src\app\heroes\heroes.component.html的<li *ngFor="let hero of heroes">改成如下:
<li *ngFor="let hero of heroes" (click)="onSelect(hero)">
接著打開檔案src\app\heroes\heroes.component.ts,目前尚未修改的hero變數應該長的像是下面這樣
將紅色框框刪除之後修改為如下:
selectedHero: Hero;
onSelect(hero: Hero): void {
this.selectedHero = hero;
}
接著再打開檔案src\app\heroes\heroes.component.html,原本有一段跟hero變數綁定的html如下
請將此紅色框框內容刪除之後,以下列內容取代, *ngif就是angular的if,這段html只有在selectedHero為true(表示有資料)的時候,才會顯示在畫面上
<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>
如此一來,頁面上基本的master detail就完成了!,click list裡面任一個hero,就會把這個hero的detail顯示在上方喔
還有一點要補充一下,就是要替已經用滑鼠選定的hero的li上色,不然用肉眼很難分辨到底剛才用滑鼠點選了哪一個,請查看目前src/app/heroes/heroes.component.css的內容,可以發現有一個class叫做.selected,這個就是會幫滑鼠選定的li上色的css class
再來請打開src\app\heroes\heroes.component.html,把下面這段加入到<li *ngFor="let hero of heroes" (click)="onSelect(hero)">的上面
我把這個寫法叫做(幫css設定加上if),當hero物件等於selectedHero物件的時候,就會套用.selected這個css。
[class.selected]="hero === selectedHero"
加好之後會長的像是這樣
<h2>My Heroes</h2>
<ul class="heroes">
<!--<li *ngFor="let hero of heroes">-->
<li *ngFor="let hero of heroes"
[class.selected]="hero === selectedHero"
(click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
此時打開瀏覽器隨便點選一個hero的話,html裡面的li就會變色囉
最後的src\app\heroes\heroes.component.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>
<h2>My Heroes</h2>
<ul class="heroes">
<!--<li *ngFor="let hero of heroes">-->
<li *ngFor="let hero of heroes"
[class.selected]="hero === selectedHero"
(click)="onSelect(hero)">
<span class="badge">{{hero.id}}</span> {{hero.name}}
</li>
</ul>
最後的src\app\heroes\heroes.component.ts內容長這樣
import { Component, OnInit } from '@angular/core';
//加入了這個import
import { Hero } from '../hero';
//把HEROES假資料import進來
import { HEROES } from '../mock-heroes';
@Component({
selector: 'app-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
//hero = 'Windstorm';
//hero原本只是字串變數,現在變成一個資料結構
// hero: Hero = {
// id: 1,
// name: 'Windstorm'
// };
selectedHero: Hero;
onSelect(hero: Hero): void {
this.selectedHero = hero;
}
heroes = HEROES;
constructor() { }
ngOnInit() {
}
}
@master detail advanced要介紹的是,將master 以及 detail元件拆開來到不同的component,便於以後維護(上面所介紹的master以及detail元件都是在同一個component裡面)
接著執行angular cli指令以新增detail專用的component
ng g c hero-detail
再來打開src/app/hero-detail/hero-detail.component.html,將內容修改如下,主要就是用*ngModel來顯示hero的detail
<div *ngIf="hero">
<h2>{{hero.name | uppercase}} Details</h2>
<div><span>id: </span>{{hero.id}}</div>
<div>
<label>name:
<input [(ngModel)]="hero.name" placeholder="name"/>
</label>
</div>
</div>
然後修改src/app/hero-detail/hero-detail.component.ts的內容如下,主要就是設定這個detail component可以跟master component做連動,設定的方式就是用@Input
import { Component, OnInit, Input } from '@angular/core';
//detail會跟master做binding,因此這邊要先做好import
import { Hero } from '../hero';
@Component({
selector: 'app-hero-detail',
templateUrl: './hero-detail.component.html',
styleUrls: ['./hero-detail.component.css']
})
export class HeroDetailComponent implements OnInit {
//另外一個component連動的設定方式,就是用@Input
@Input() hero: Hero;
constructor() { }
ngOnInit() {
}
}
最後就是把原本hero component的detail的部分拿掉,src/app/heroes/heroes.component.html把detail的內容拿掉之後,應該會長的像是下面這樣
塞值到@Input的寫法就像是這樣:[被塞的變數] = 要塞進去的變數
<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>
<app-hero-detail [hero]="selectedHero"></app-hero-detail>
打開瀏覽器的畫面變成這樣(其實沒啥變,只是排版位置改了一下)
最後終於把master detail分開來顯示囉!在實務上這是常見的設計,很好用的!寫好這個功能,通常可以運用在多個系統功能
最後補充目前為止做到這邊的整個專案的壓縮檔下載,方便大家自行在家確認程式碼
https://www.dropbox.com/s/0tbki3sye88hz8k/angular-tour-of-heros%20-%20%E5%AE%8C%E6%88%90master%20detail.rar?dl=0
參考資料:
Master/Detail Components
https://angular.io/tutorial/toh-pt3
Display a Heroes List
https://angular.io/tutorial/toh-pt2