Angular 2:如何实现Material Table与Material Spinner的互斥显示?
Angular Material Table与Spinner互斥显示实现方案
嘿,这个需求其实很常见,核心就是通过一个状态变量来控制两者的显示/隐藏,我给你两种常用的实现方式,你可以根据自己的代码风格选:
方式一:手动管理加载状态变量
这是最直观的方式,适合大多数场景:
1. 在组件类中定义状态变量
首先在你的组件.ts文件里,声明一个布尔变量来标记加载状态,初始值设为true(因为页面加载时先显示Spinner):
import { Component, OnInit } from '@angular/core'; import { YourDataService } from './your-data.service'; @Component({ selector: 'app-your-component', templateUrl: './your-component.component.html', }) export class YourComponent implements OnInit { // 加载状态变量 isLoading = true; // 表格数据 tableData: any[] = []; // 表格列配置 displayedColumns = ['name', 'age', 'email']; constructor(private dataService: YourDataService) {} ngOnInit(): void { this.loadTableData(); } loadTableData(): void { // 开始加载时,设置为true this.isLoading = true; this.dataService.fetchYourData().subscribe({ next: (data) => { this.tableData = data; }, error: (err) => { console.error('数据加载失败:', err); // 即使出错,也要隐藏加载器 this.isLoading = false; }, complete: () => { // 加载完成(无论成功失败),隐藏加载器 this.isLoading = false; }, }); } }
2. 在模板中用*ngIf控制显示
然后在你的组件.html文件里,用*ngIf根据isLoading的值来切换表格和Spinner的显示:
<!-- 加载Spinner:只有当isLoading为true时显示 --> <div *ngIf="isLoading" class="loading-container"> <mat-spinner diameter="50"></mat-spinner> </div> <!-- Material表格:只有当isLoading为false时显示 --> <mat-table *ngIf="!isLoading" [dataSource]="tableData"> <!-- 示例列定义 --> <ng-container matColumnDef="name"> <mat-header-cell *matHeaderCellDef> 姓名 </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.name}} </mat-cell> </ng-container> <ng-container matColumnDef="age"> <mat-header-cell *matHeaderCellDef> 年龄 </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.age}} </mat-cell> </ng-container> <ng-container matColumnDef="email"> <mat-header-cell *matHeaderCellDef> 邮箱 </mat-header-cell> <mat-cell *matCellDef="let element"> {{element.email}} </mat-cell> </ng-container> <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row> <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row> </mat-table>
3. 给Spinner加个居中样式
为了让Spinner在页面中间显示,你可以在组件的CSS里加个简单的样式:
.loading-container { display: flex; justify-content: center; align-items: center; height: 300px; /* 可以根据表格预期高度调整 */ }
方式二:使用Async Pipe(更简洁)
如果你的数据是通过Observable获取的,推荐用Angular的async pipe,它会自动帮你管理订阅和状态,不用手动设置isLoading:
1. 组件类中定义数据Observable
import { Component } from '@angular/core'; import { Observable } from 'rxjs'; import { YourDataService } from './your-data.service'; @Component({ selector: 'app-your-component', templateUrl: './your-component.component.html', }) export class YourComponent { // 直接用Observable存储数据 tableData$: Observable<any[]>; displayedColumns = ['name', 'age', 'email']; constructor(private dataService: YourDataService) { this.tableData$ = this.dataService.fetchYourData(); } }
2. 模板中用*ngIf结合else块
<!-- 表格:当数据加载完成时显示 --> <mat-table *ngIf="tableData$ | async as tableData; else loadingBlock" [dataSource]="tableData"> <!-- 你的表格列定义(和方式一一致) --> </mat-table> <!-- 加载Spinner的else块 --> <ng-template #loadingBlock> <div class="loading-container"> <mat-spinner diameter="50"></mat-spinner> </div> </ng-template>
这种方式更符合Angular的响应式编程理念,还能避免内存泄漏(因为async pipe会自动取消订阅)。
关键注意点
- 无论数据加载成功还是失败,都要确保Spinner能隐藏,避免用户一直看到加载状态
- 如果表格本身有数据为空的情况,可以在表格显示的条件里再加个
tableData.length > 0,同时添加空状态提示(比如“暂无数据”的文字)
内容的提问来源于stack exchange,提问作者donkeykong
相关产品推荐
相关产品推荐

