今天我們要來講Angular Material的Menu元件,Menu可以說是非常具有歷史性的功能,使用機會也不低,只要有一系列的選擇要濃縮在一個範圍內時,就是使用Menu的好時機,接下來就讓我們看看Angular Material強大的Menu元件吧!
在Material Design的Menu設計指南中,Menu可以用來顯示一系列的選項,每一列就是一個選項,通常由一個按鈕,或一個簡單的文字label開始,在畫面上進行立體的呈現,而不會影響到其他元素的排版。
在桌面應用上Menu可以是多層串接的,在行動裝置或平板上則建議一層簡單的Menu就好,另外Menu的選項也應該是可以被disable的。
圖片來源:https://material.io/guidelines/components/menus.html#
要使用Menu元件,首先要先加入MatMenuModule
。
我們使用<mat-menu>
來為原來toolbar的message icon加上Menu選單,首先我們可以再任意地方加入<mat-menu>
與<mat-menu-item>
組合的選單。
<mat-menu #messageMenu="matMenu">
<button mat-menu-item>最新訊息</button>
<button mat-menu-item>訊息設定</button>
</mat-menu>
這時候畫面上還不會有任何資料,還需需要一個可以觸發顯示選單的來源,我們加在toolbar上的message icon上
<button mat-icon-button [matMenuTriggerFor]="messageMenu" #menuTrigger="matMenuTrigger">
<mat-icon>message</mat-icon>
</button>
上面程式我們透過matMenuTriggerFor
來設定這個按鈕會觸發哪一個menu元件,這時候我們可以執行看看結果:
點擊看看原來的message icon按鈕,可以發現menu選單就跳出來啦!這時候我們可以使用上下鍵來切換focus的選項,也可以按下Enter鍵來觸發按鈕的click事件,操作上超級方便的!
要在程式中開啟選單很容易,只要找到matMenuTriggerFor
,再觸發他的openMenu()
方法就可以打開menu,透過closeMenu()
則能夠動態的關閉menu,另外我們也可以透過toggleMenu()
來開關menu的顯示狀態
<button mat-raised-button (click)="menuTrigger.toggleMenu()">開啟訊息設定</button>
效果如下:
<mat-menu>
預設會在出現時把整個menuTrigger覆蓋掉,同時也會根據目前所在的位置來決定選單生長的方向,例如按鈕在畫面的右邊的話,選單預設會往左邊長,在畫面上方的話,選單預設會往下長,總之就是會盡量讓整個menu在畫面中可以被看到就對了,我們可以能夠透過xPosition
和yPosition
,來控制生長的方向
after
(預設值、從start往end的方向長,通常是從左到右)或before
(從end往start的方向長,通常是從右到左)。below
(預設值、從上往下長)或above
(從下往上長)舉例來說,一個沒有設定xPosition
和yPosition
,且生長方向沒有阻礙時的程式碼和畫面如下:
<div style="text-align:center">
<button mat-raised-button [matMenuTriggerFor]="positionMenu">開啟訊息設定,這是一條比較長的按鈕,好確認Menu的生長方向</button>
<mat-menu #positionMenu="matMenu">
<button mat-menu-item>訊息1</button>
<button mat-menu-item>訊息2</button>
</mat-menu>
</div>
當我們調整xPosition
和yPosition
如下時:
<mat-menu #positionMenu="matMenu" xPosition="before" yPosition="above">
<button mat-menu-item>訊息1</button>
<button mat-menu-item>訊息2</button>
</mat-menu>
可以看到生長的方向就變了,有趣的是當我們往下捲動螢幕時,由於menu即將碰到頂端,會立刻改爲往下生長,盡可能讓選單可以被看到,只能說Angular Material既貼心又聰明啊!
同樣的當生長方向收到阻礙時,Angular Material會自動幫我們計算要成長的方向
<!-- 按鈕在畫面的很上方,即使設定往上長,當上方空間不足時,會自動往下生長 -->
<mat-menu #positionMenu="matMenu" xPosition="before" yPosition="above">
<button mat-menu-item>訊息1</button>
<button mat-menu-item>訊息2</button>
...
<button mat-menu-item>訊息5</button>
</mat-menu>
另外,我們也可以設定[overlapTrigger]="false"
,如此一來,選單就永遠不會遮住我們的trigger:
<mat-menu #messageMenu="matMenu" [overlapTrigger]="false">
<button mat-menu-item>最新訊息</button>
<button mat-menu-item>訊息設定</button>
</mat-menu>
<button mat-icon-button [matMenuTriggerFor]="messageMenu" #menuTrigger="matMenuTrigger">
<mat-icon>message</mat-icon>
</button>
menu選單可以是巢狀的,要使用巢狀的選單沒有什麼新技巧,一樣把子選單使用<mat-menu>
設計好,然後在原來的選單選項中加入matMenuTriggerFor
即可:
<button mat-raised-button [matMenuTriggerFor]="positionMenu">巢狀選單demo</button>
<mat-menu #positionMenu="matMenu">
<button mat-menu-item [matMenuTriggerFor]="subMenu1">訊息1</button>
<button mat-menu-item [matMenuTriggerFor]="subMenu2">訊息2</button>
<button mat-menu-item>訊息3</button>
</mat-menu>
<mat-menu #subMenu1="matMenu">
<button mat-menu-item>
<mat-icon>person</mat-icon>
訊息 1-1
</button>
<button mat-menu-item>
<mat-icon>favorite</mat-icon>
訊息 1-2
</button>
<button mat-menu-item>
<mat-icon>thumb_up</mat-icon>
訊息 1-3
</button>
</mat-menu>
<mat-menu #subMenu2="matMenu">
<button mat-menu-item>
<mat-icon>delete</mat-icon>
訊息 2-1
</button>
<button mat-menu-item disabled>
<mat-icon>settings</mat-icon>
訊息 2-2
</button>
</mat-menu>
我們在這邊順便搭配了<mat-icon>
以及嘗試為button加入disabled
屬性,可以看到搭配上完全都沒有問題,排版依然很順暢,同時我們也能使用左右鍵切換子選單:
當要呈現的選單多的時候,除了選擇用巢狀的選單以外,用一個divider分隔也是個不錯的選擇,可以減少子項目難以分類的煩惱,在行動裝置的呈現上也會比較清楚。
還記得我們在昨天介紹List時有提到一個<mat-divider>
嗎?雖然官方的Menu文件沒有提到,但<mat-divider>
其實一樣可以在<mat-menu>
中使用:
<mat-menu #positionMenu="matMenu">
<button mat-menu-item [matMenuTriggerFor]="subMenu1">訊息1</button>
<button mat-menu-item [matMenuTriggerFor]="subMenu2">訊息2</button>
<mat-divider></mat-divider>
<button mat-menu-item>訊息3</button>
</mat-menu>
成果如下,一條分隔線就出現啦:
當然,你還是必須要載入
MatListModule
才可以。
關於Menu的使用基本上不會很困難,但實用性卻很高,要調整顯示風格也不會是太困難的事情。
Angular Material在Menu的設計上非常用心,儘管是web application,但在操作上我們依然可以輕鬆地使用方向鍵來切換不同的選項,同時也可以使用Enter來確認執行選項,可以說是非常貼心方便的設計!
介紹到這邊,整個基本的後台畫面就已經大致上成形了!明天開始我們將花幾天的時間透過一個問卷調查的頁面,來介紹Angular Material中各種不同的表單元件的使用,這些表單元件都有很豐富的動態效果,但使用上非常顯示明確,不會被這些效果給混淆,敬請期待吧!!
本日的程式碼GitHub:https://github.com/wellwind/it-ironman-demo-angular-material/tree/day-08-menu
分支:day-08-menu
不知不覺,這系列文章已經超過50個人訂閱了,真的是對我很大的一個鼓勵,也不白費我每篇文章都花3個小時左右絞盡腦汁的寫出來,在這邊感謝各位訂閱者,也感謝有在下面留言發問、提供意見的朋友,讓我更有信心把這系列寫下去!最後虛榮的祈禱一下完賽前訂閱數可以破百吧XD
mat-menu-Item disable 後,怎樣enable? disabled 是directive嗎? 如何用boolean 控制狀態? 謝
disabled只是一個屬性而已, 跟一般<button disabled>
是一樣的,因此可以如下:
disable:
<button mat-menu-item [disabled]="true">
enable:
<bitton mat-menu-item [disabled]="false">
got it
請問有辦法直接在ToolBar上直接顯示Menu的內容嗎? 大概是點擊Button在Button左側顯示出Menu的內容
Menu 的設計預設是會擋住內容的,如果要部擋住內容,目前只能自己套 CDK 了
多謝,已修正囉