iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 22
1
Modern Web

Angular Material完全攻略系列 第 22

[Angular Material完全攻略] Day 22 - 收件夾頁面(2) - Tabs

  • 分享至 

  • xImage
  •  

昨天我們介紹了Expansaion Panels,替收件夾的左邊加上了基本的分類資訊,今天讓我們來使用Angular Material的Tab元件,來把右邊也填入些東西!

Tab元件可以說是許許多多UI都會用到的功能,使用上雖然簡單,但也有許多不同的呈現模式,可以說是最簡單也最複雜的元件之一,接下來就立刻來看看有些什麼變化吧!

關於Material Design中的Tabs

Material Design的Tabs設計指南中,Tab提供了一個簡易的方式來切換不同的畫面;Tab使用頁籤的方式管理不同的畫面,並且一次只會顯示一個畫面。

Material Design - Tabs

開始使用Angular Material的Tabs

要使用Tabs元件,需要加入MatTabsModule,之後我們可以使用<mat-tab-group><mat-tab>來建立tabs。

使用mat-tab-group與mat-tab

跟許多群組型的元件都差不多,我們可以使用<mat-tab-group>作為一個最外層的tab容器,並在裡面放置數個<mat-tab>

<mat-tab-group>
  <mat-tab label="郵件列表">
    郵件列表清單
  </mat-tab>
  <mat-tab label="系統設定">
    系統設定表單
  </mat-tab>
</mat-tab-group>

成果如下:

Basic Tabs

使用selectedIndex改變選取的tab

我們可以透過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>

成果如下:

SelectedIndex

mat-tab-group的相關事件

Angular Material的tabs是可以透過鍵盤切換的,我們可以使用左右方向鍵focus到不同的tab,再使用SPACEENTER確認切換動作,這時候我們可以使用focusChange事件來得知focus狀態的變更,另外也有selectedIndexChangeselectedTabChange事件:

<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 Events

複雜的tab label顯示

剛才我們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>

成果如下:

Tab label

mta-tab-group固定寬度時,設定stretch模式

當我們為<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>

成果如下:

Stretch Tab

mta-tab-group固定寬度時,tab很多的顯示模式

當tab很多,但<mat-tab-group>寬度不夠時該怎麼辦呢?我們不用做任何設定,Angular Material都幫我們設計好了,tab標籤不會因為過多而換行,破壞版面,而是會顯示一個可以左右移動的按鈕,方便我們切換tab:

Many tabs

設定mat-tab-group的顏色

mat-tab-goup的顏色也是可以設定的,我們可以使用backgroundColor來設定背景顏色,使用color來設定focus的tab底部顏色,例如:

<mat-tab-group backgroundColor="primary" color="accent" ...>
  ...
</mat-tab-group>

成果如下:

Colored Tab

使用headerPosition改變tab的位置

預設的tabs都是顯示在上方,但我們也能夠設定headerPosition="below",讓tab呈現在畫面下方:

<mat-tab-group headerPosition="below" ...>
  ...
</mat-tab-group>

成果如下:

HeaderPosition Below

設定disabled狀態

當舞們不希望某個<mat-tab>能夠被選取時,可以為它加上disabled,變成不可選取的狀態:

<mat-tab-group>
  <mat-tab>
    ...
  </mat-tab>
  <mat-tab disabled="true">
    ...
  </mat-tab>
</mat-tab-group>

成果如下:

Disabled Tab

設定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

目前我們已經把收件夾的基本畫面都組好了,看起來如下:

Inbox Preview

明天我們將使用table元件,來把郵件清單給補起來,同時學習table多采多姿的組合技,敬請期待!

相關資源


上一篇
[Angular Material完全攻略] Day 21 - 收件夾頁面(1) - Expansion Panels
下一篇
[Angular Material完全攻略] Day 23 - 收件夾頁面(3) - Table (基礎功能)
系列文
Angular Material完全攻略34
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
Charles Wang
iT邦新手 5 級 ‧ 2020-05-07 16:53:13


"使用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 吧?有這個陣列,最大值也就自然有囉

0
Charles Wang
iT邦新手 5 級 ‧ 2021-07-28 08:48:58

請問
文中說到
"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

我要留言

立即登入留言