昨天我們介紹了Expansaion Panels,替收件夾的左邊加上了基本的分類資訊,今天讓我們來使用Angular Material的Tab元件,來把右邊也填入些東西!
Tab元件可以說是許許多多UI都會用到的功能,使用上雖然簡單,但也有許多不同的呈現模式,可以說是最簡單也最複雜的元件之一,接下來就立刻來看看有些什麼變化吧!
在Material Design的Tabs設計指南中,Tab提供了一個簡易的方式來切換不同的畫面;Tab使用頁籤的方式管理不同的畫面,並且一次只會顯示一個畫面。
要使用Tabs元件,需要加入MatTabsModule
,之後我們可以使用<mat-tab-group>
與<mat-tab>
來建立tabs。
跟許多群組型的元件都差不多,我們可以使用<mat-tab-group>
作為一個最外層的tab容器,並在裡面放置數個<mat-tab>
:
<mat-tab-group>
<mat-tab label="郵件列表">
郵件列表清單
</mat-tab>
<mat-tab label="系統設定">
系統設定表單
</mat-tab>
</mat-tab-group>
成果如下:
我們可以透過selectedIndex
,來設定要選取第幾個tab,這個selectedIndex
是two way binding的,所以我們也能在手動切換tab時,得知目前的被選取的tab index:
<button mat-button (click)="tabIndex = tabIndex - 1">上一頁</button>
<button mat-button (click)="tabIndex = tabIndex + 1">下一頁</button>
<p>目前的selectedIndex: {{ tabIndex }}</p>
<mat-tab-group [(selectedIndex)]="tabIndex">
<mat-tab label="郵件列表">
郵件列表清單
</mat-tab>
<mat-tab label="系統設定">
系統設定表單
</mat-tab>
<mat-tab label="其他">
其他畫面
</mat-tab>
</mat-tab-group>
成果如下:
Angular Material的tabs是可以透過鍵盤切換的,我們可以使用左右方向鍵
focus到不同的tab,再使用SPACE
或ENTER
確認切換動作,這時候我們可以使用focusChange
事件來得知focus狀態的變更,另外也有selectedIndexChange
及selectedTabChange
事件:
<mat-tab-group [(selectedIndex)]="tabIndex"
(focusChange)="tabFocusChange($event)"
(selectedIndexChange)="tabSelectedIndexChange($event)"
(selectedTabChange)="tabSelectedTabChange($event)">
...
</mat-tab-group>
TypeScript程式如下:
@Component({ ... })
export class InboxComponent {
tabFocusChange($event: MatTabChangeEvent) {
console.log(`focus變更,indx:${$event.index}`);
}
tabSelectedIndexChange($event: number) {
console.log(`selectedIndex變更,index:${$event}`);
}
tabSelectedTabChange($event: MatTabChangeEvent) {
console.log(`selectedTab變更,index:${$event.index}`);
}
}
成果如下:
剛才我們tab顯示的label都是使用<mat-tab label="xxx">
的方式,這樣只能設定純文字,如果希望更複雜的設定,可以使用<ng-template mat-tab-label>
的方式,來設定tab的label:
<mat-tab-group>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon>inbox</mat-icon>
郵件列表
</ng-template>
郵件列表清單
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon>settings</mat-icon>
系統設定
</ng-template>
系統設定表單
</mat-tab>
</mat-tab-group>
成果如下:
當我們為<mat-tab-group>
設定一個固定寬度時,可以加上mat-stretch-tabs
這個directive,此時所有tab頁籤就會平均分配寬度,例<mat-tab-group>
寬度設為300時,每個<mat-tab>
的label就會佔據100(300/3)的寬度:
<mat-tab-group mat-stretch-tabs>
<mat-tab label="tab1"></mat-tab>
<mat-tab label="tab2"></mat-tab>
<mat-tab label="tab3"></mat-tab>
</mat-tab-group>
成果如下:
當tab很多,但<mat-tab-group>
寬度不夠時該怎麼辦呢?我們不用做任何設定,Angular Material都幫我們設計好了,tab標籤不會因為過多而換行,破壞版面,而是會顯示一個可以左右移動的按鈕,方便我們切換tab:
mat-tab-goup
的顏色也是可以設定的,我們可以使用backgroundColor
來設定背景顏色,使用color
來設定focus的tab底部顏色,例如:
<mat-tab-group backgroundColor="primary" color="accent" ...>
...
</mat-tab-group>
成果如下:
預設的tabs都是顯示在上方,但我們也能夠設定headerPosition="below"
,讓tab呈現在畫面下方:
<mat-tab-group headerPosition="below" ...>
...
</mat-tab-group>
成果如下:
當舞們不希望某個<mat-tab>
能夠被選取時,可以為它加上disabled
,變成不可選取的狀態:
<mat-tab-group>
<mat-tab>
...
</mat-tab>
<mat-tab disabled="true">
...
</mat-tab>
</mat-tab-group>
成果如下:
設定disabled的tab就會變成灰色的字,而且連focus都無法做到啦!
今天我們介紹了Tab元件,Tab在許許多多的UI呈現上都佔據了很重要的角色,使用的頻率非常非常的高,儘管在Angular Material中,要建立一個基本的tab並不困難,但tab本身卻有非常多的變化,來滿足各種不同的tab呈現需求,如顏色、方向等等,都是很常見需要調整的情境,好好的把tab學起來,就不怕面臨各種不同的需求囉!
本日的程式碼GitHub:https://github.com/wellwind/it-ironman-demo-angular-material/tree/day-22-tabs
分支:day-22-tabs
目前我們已經把收件夾的基本畫面都組好了,看起來如下:
明天我們將使用table元件,來把郵件清單給補起來,同時學習table多采多姿的組合技,敬請期待!
在
"使用selectedIndex改變選取的tab"
這邊時
因為按鈕邏輯是
tabIndex = tabIndex - 1
tabIndex = tabIndex + 1
想問:
那你怎樣處理當按了太多次,
tabIndex變成負很多的時候的狀況
或是tabIndex變成正很多的時候的狀況
因為當tabIndex的值大於現有tab數時,
這個上一頁和下一頁的按鈕從使用者角度來看就和失效一樣
即使數字還是真的有在那邊+1或是-1
等等試試能不能直接用function管理
這是示範程式的作法,確實在功能要完整時,寫一個 function 接 click 事件,並判斷小於 0 時沒有反應會比較好。
或是按鈕判斷如果 tabIndex 為 0 時 disabled 掉
那抱歉想問如果是動態增加的tab,
有辦法抓取現有動態增加的tab最大數值嗎?
因為避免增加數值大於現有tabIndex的數值
看官方的示範文件也沒處理這塊
既然是動態增加 tab,代表勢必會有個陣列搭配 *ngFor
來產生 tab 吧?有這個陣列,最大值也就自然有囉
請問
文中說到
"mta-tab-group固定寬度時,tab很多的顯示模式"
那material 的 stepper 也有類似這種顯示模式嗎?
還是說有甚麼其他的參數可以使用
因為在IPAD版中,我的stepper 過長的標題會變成 "..."
不然折衷辦法就是寫以下的CSS了?
//設置stepper的標題換行
:host ::ng-deep .mat-step-label.mat-step-label {
text-overflow: inherit;
white-space: normal;
}
以及直式橫式根據視窗responsive的stepper變換好像到material 12才有範例(?
目前應該沒有相關的設定喔,可能還是需要自行設定 CSS,或改用 tabs