Angular 14中Mat-Table基于条件隐藏行失效问题
解决Angular 14 Mat-Table按角色和字段值隐藏行的问题
我在Angular 14项目中使用Mat-Table组件,需求是:当当前用户角色为quality且数据行的element.tqp值为false时,隐藏该行。尝试给行元素绑定[ngClass]="(element.tqp == false && (role$ | async) === userQuality) ? 'displayNone' : ''",但该行并未成功隐藏。
组件列定义与数据源
displayedColumns: string[] = ['anomalyId', 'zone', 'hour', 'piece', 'category', 'description','noOfImage', 'scotchPoses','scotchTraiter','tqp','listOfDecision','comments', 'retoucher','valider']; displayedColumns1: string[] = ['anomalyId', 'zone', 'hour', 'piece', 'category', 'description','noOfImage','createdDate', 'scotchPoses','scotchTraiter','tqp','listOfDecision','visaDecision','comments', 'retoucher','visaRetoucher','valider','visaValidation']; dataSource = new MatTableDataSource();
HTML代码
<table mat-table [dataSource]="dataSource"> <ng-container matColumnDef="anomalyId"> <th mat-header-cell *matHeaderCellDef >N<span>°</span> </th> <td mat-cell *matCellDef="let element"> <p>{{element.anomalyId}}</p> </td> </ng-container> <ng-container matColumnDef="zone"> <th mat-header-cell *matHeaderCellDef> Zone </th> <td mat-cell *matCellDef="let element" > <p>{{element.zone}} </p> </td> </ng-container> <ng-container matColumnDef="hour"> <th mat-header-cell *matHeaderCellDef> Pos </th> <td mat-cell *matCellDef="let element" > <p>{{element.hour}} </p> </td> </ng-container> <ng-container matColumnDef="piece"> <th mat-header-cell *matHeaderCellDef > Pièce</th> <td mat-cell *matCellDef="let element"> <p> {{element.piece}} </p> </td> </ng-container> <ng-container matColumnDef="category"> <th mat-header-cell *matHeaderCellDef> Catégorie </th> <td mat-cell *matCellDef="let element" > <p> {{element.category}} </p> </td> </ng-container> <ng-container matColumnDef="description"> <th mat-header-cell *matHeaderCellDef> Description Anomalie </th> <td mat-cell *matCellDef="let element" > <p> {{element.description}}</p> </td> </ng-container> <ng-container matColumnDef="noOfImage"> <th mat-header-cell *matHeaderCellDef > Image </th> <td mat-cell *matCellDef="let element" > {{element.noOfImage}} </td> </ng-container> <ng-container matColumnDef="createdDate" > <th mat-header-cell *matHeaderCellDef> Visa Control </th> <td mat-cell *matCellDef="let element" > {{element.createdDate | date: 'dd/MM/yyyy'}} {{element.createdBy}} </td> </ng-container> <ng-container matColumnDef="scotchPoses"> <th mat-header-cell *matHeaderCellDef > Scotchs posés </th> <td mat-cell *matCellDef="let element" > <div *ngFor="let scotch of element.scotchPoses">{{scotch.scotchCount}} </div> <!-- {{element.scotchs_poses}} --> </td> </ng-container> <ng-container matColumnDef="scotchTraiter"> <th mat-header-cell *matHeaderCellDef >Scotchs à traiter</th> <td mat-cell *matCellDef="let element" > <div *ngFor="let scotch of element.scotchTraiter"> <span>{{scotch.scotchTraiter}} </span> </div> </td> </ng-container> <ng-container matColumnDef="tqp"> <th mat-header-cell *matHeaderCellDef >TQP </th> <td mat-cell *matCellDef="let element" > <mat-checkbox [checked]="element.tqp" disabled></mat-checkbox> </td> </ng-container> <ng-container matColumnDef="listOfDecision"> <th mat-header-cell *matHeaderCellDef>Décision retouche </th> <td mat-cell *matCellDef="let element" (click)="openAnomalyStatusDialog(element.listOfDecision,element.tqp,element)" > <div *ngFor="let decision of element.listOfDecision"> <span>{{decision.decisionName}} </span> </div> <!-- <div><em>En Cours</em></div> --> </td> </ng-container> <ng-container matColumnDef="visaDecision"> <th mat-header-cell *matHeaderCellDef>Visa decision </th> <td mat-cell *matCellDef="let element" > <div *ngFor="let decision of element.visaDecision"> <span>{{decision.visaDecisionBy}}{{decision.visaDecisionDate | date: 'dd/MM/yyyy'}}</span> </div> </td> </ng-container> <ng-container matColumnDef="comments"> <th mat-header-cell *matHeaderCellDef >Commentaires </th> <td mat-cell *matCellDef="let element" > <div *ngFor="let comm of element.comments; let i = index" (click)="openAnomalyCommentDialog(comm)"> <span matTooltip="{{comm.comment}}">{{ (comm.comment).length > 60 ? (comm.comment | slice:0:59) + '...' : (comm.comment)}}</span> </div> </td> </ng-container> <ng-container matColumnDef="retoucher"> <th mat-header-cell *matHeaderCellDef >Retoucher </th> <td mat-cell *matCellDef="let element"> <div *ngFor="let retouch of element.retoucher"> <mat-checkbox [checked]="retouch.retouch"></mat-checkbox> </div> </td> </ng-container> <ng-container matColumnDef="visaRetoucher"> <th mat-header-cell *matHeaderCellDef>Visa Retouch </th> <td mat-cell *matCellDef="let element"> <div *ngFor="let retouch of element.visaRetoucher"> <span>{{retouch.retouchBy}}{{retouch.retouchDate}}</span> </div> </td> </ng-container> <ng-container matColumnDef="valider"> <th mat-header-cell *matHeaderCellDef > Valider</th> <td mat-cell *matCellDef="let element"> <div *ngFor="let validation of element.valider"> <mat-checkbox [checked]="validation.validate"></mat-checkbox> </div> </td> </ng-container> <ng-container matColumnDef="visaValidation"> <th mat-header-cell *matHeaderCellDef>Visa Validation </th> <td mat-cell *matCellDef="let element"> <div *ngFor="let validation of element.visaValidation"> <span>{{validation.validateBy}}{{validation.validateDate}}</span> </div> </td> </ng-container> <tr mat-header-row *matHeaderRowDef="show == false ? displayedColumns :displayedColumns1;sticky: true " ></tr> <tr mat-row *matRowDef="let row; columns: show == false ? displayedColumns :displayedColumns1;"></tr> </table>
解决方法
1. 修复mat-row的绑定问题
当前的mat-row未添加[ngClass]绑定,需将绑定加到<tr mat-row>上,且模板变量是row而非element:
<tr mat-row *matRowDef="let row; columns: show == false ? displayedColumns :displayedColumns1;" [ngClass]="(row.tqp === false && (role$ | async) === userQuality) ? 'displayNone' : ''"> </tr>
2. 确保CSS类生效
检查全局样式或组件样式中是否正确定义displayNone类,Mat-Table行有默认样式,需用!important强制覆盖:
.displayNone { display: none !important; }
3. 推荐方案:使用数据源过滤
直接通过MatTableDataSource的filterPredicate过滤数据,比CSS隐藏更高效:
// 假设角色类型定义 userQuality = 'quality'; ngOnInit() { // 角色变化时触发重新过滤 this.role$.subscribe(() => { this.dataSource.filter = 'refresh'; }); this.dataSource.filterPredicate = (data: any, filter: string) => { // 先获取当前角色(若role$是BehaviorSubject可直接取value,否则需订阅保存到变量) const currentRole = this.role$.value; // 角色为quality且tqp为false时过滤该行,否则保留 return !(currentRole === this.userQuality && data.tqp === false); }; }
4. 验证角色匹配正确性
确认role$返回的角色字符串与userQuality完全匹配(大小写、拼写一致),可临时在模板中添加调试代码:
<div>当前角色: {{ role$ | async }}</div> <div>userQuality值: {{ userQuality }}</div>
内容的提问来源于stack exchange,提问作者tripti tiwari
相关产品推荐
相关产品推荐

