在實作表單的手風琴之前,先利用 Button Toggle 來實作一般與收合兩種清單的切換,此元件是一種可單選或多選的選擇型按鈕。在引用 MatButtonToggleModule
模組後,就可以 <mat-button-toggle-group>
標籤,此標籤的 appearance
屬性用來設定所顯示的樣式;若要允許多選的話,則會設定 multiple
屬性。
<mat-button-toggle-group>
<mat-button-toggle value="list">一般表格</mat-button-toggle>
<mat-button-toggle value="expansion">收合表格</mat-button-toggle>
</mat-button-toggle-group>
如上面所示,預設顯示所選擇的對象會有勾選符號,若不希望顯示則可以設定 hideSingleSelectionIndicator
或 hideMultipleSelectionIndicator
屬性來隱藏,前者針對的是單選,後者則為多選。
然而,若希望整個應用程式針對上面的 appearance
、hideSingleSelectionIndicator
或 hideMultipleSelectionIndicator
等屬性都使用一樣的設定,我們可以實作 MatButtonToggleDefaultOptions
這個介面。
@Injectable()
export class CustomButtonToggleOptions
implements MatButtonToggleDefaultOptions
{
appearance: MatButtonToggleAppearance = 'standard';
hideSingleSelectionIndicator = true;
hideMultipleSelectionIndicator = true;
disabledInteractive = true;
}
並且在 app.config
抽換掉 MAT_BUTTON_TOGGLE_DEFAULT_OPTIONS
令牌。
{
provide: MAT_BUTTON_TOGGLE_DEFAULT_OPTIONS,
useClass: CustomButtonToggleOptions,
},
當使用者選擇 Button Toggle 的狀態時,我們可以利用 change
或 valueChange
兩個事件來取得當前選擇狀態。
<mat-button-toggle-group (valueChange)="viewType.set($event)">
<mat-button-toggle value="table" checked="true">一般表格</mat-button-toggle>
<mat-button-toggle value="expansion">收合表格</mat-button-toggle>
</mat-button-toggle-group>
也可以與 Reactive Form 整合,設定繫結 FormControl 來記錄所選擇的狀態。
<mat-button-toggle-group [formControl]="viewControl">
<mat-button-toggle value="list">一般清單</mat-button-toggle>
<mat-button-toggle value="expansion">收合清單</mat-button-toggle>
</mat-button-toggle-group>
要在 Angular Material 的 Table 實作收合列的功能,需要先使用 multiTemplateDataRows
來允許顯示多資料列。接著,如之前資料表清單所描述,先定義收合列所需要的欄位內容。
<ng-container matColumnDef="id">
<td mat-cell *matCellDef="let row">{{ row.id }}</td>
</ng-container>
<ng-container matColumnDef="subject">
<td mat-cell *matCellDef="let row" colspan="3">{{ row.subject }}</td>
</ng-container>
<ng-container matColumnDef="project">
<td mat-cell *matCellDef="let row">
<div [@detailExpand]="row == expandedElement ? 'expanded' : 'collapsed'">
{{ row.projectName }}
</div>
</td>
</ng-container>
在上面程式中,也定義了在開合過程中的動畫設定,此會對應到元件裝飾器中的 animations
設定。
@Component({
...
animations: [
trigger('detailExpand', [
state('collapsed,void', style({ height: '0px', minHeight: '0' })),
state('expanded', style({ height: '*' })),
transition(
'expanded <=> collapsed',
animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')
),
]),
],
})
最後,設定在點選資料列時記錄收合的對象,以及收合列的欄位設定,並將此列的高預設為 0。
<tr
mat-row
*matRowDef="let row; columns: ['id', 'subject']"
(click)="expandedElement = expandedElement === row ? null : row"
></tr>
<tr
mat-row
*matRowDef="let row; columns: ['project', 'tags', 'content']"
[style.height.px]="0"
></tr>
除了在 Table 中實作的收合的功能外,Angular Material 也有提供 Expansion Panel 實入手風琴。接下來,我們在今日工作的側邊欄使用 Expansion Panel 與 List 來顯示未完成與已完成事項。