Angular中ngIf条件为false时仍渲染空div的问题
解决Angular模板循环中空div导致的多余空白问题
你的问题核心是外层div由*ngFor直接控制,不管内部*ngIf条件是否成立,*ngFor都会为每个数组项生成这个div。当条件不满足时,div内无内容,就变成了空div,最终导致多余空白。
下面是两个直接可行的解决办法:
方法1:用<ng-container>承载*ngFor(推荐)
<ng-container>是Angular提供的虚拟容器,不会被渲染成真实DOM元素。把*ngFor放在它上面,就能彻底避免生成空的外层容器:
<div *ngIf="fruit$ | async as fruits"> <!-- NOT bananas --> <ng-container *ngFor="let fruit of fruits"> <mat-card *ngIf="!fruit.isBanana" [fruit]="fruit"></mat-card> </ng-container> <!-- Bananas --> <ng-container *ngFor="let fruit of fruits"> <mat-card *ngIf="fruit.isBanana" [fruit]="fruit"></mat-card> </ng-container> </div>
这种写法下,只有当*ngIf条件满足时,对应的mat-card才会被渲染,完全不会生成空容器。
方法2:需保留外层div结构时的写法
如果确实需要给每个卡片加外层div(比如添加样式),可以把*ngIf移到外层div上,同时用<ng-container>承载*ngFor(Angular不允许同一个元素同时使用*ngFor和*ngIf):
<div *ngIf="fruit$ | async as fruits"> <!-- NOT bananas --> <ng-container *ngFor="let fruit of fruits"> <div *ngIf="!fruit.isBanana"> <mat-card [fruit]="fruit"></mat-card> </div> </ng-container> <!-- Bananas --> <ng-container *ngFor="let fruit of fruits"> <div *ngIf="fruit.isBanana"> <mat-card [fruit]="fruit"></mat-card> </div> </ng-container> </div>
此时只有条件满足时,才会生成外层div和内部的mat-card,不会出现空div。
额外优化建议
虽然你提到项目需求必须分两次展示,但如果想优化性能,可以在组件内提前将数组分组,避免两次遍历原数组:
fruits$ = this.fruitService.getFruits().pipe( map(fruits => ({ nonBananas: fruits.filter(f => !f.isBanana), bananas: fruits.filter(f => f.isBanana) })) );
模板中直接遍历分组后的数组:
<div *ngIf="fruits$ | async as fruitGroups"> <!-- NOT bananas --> <div *ngFor="let fruit of fruitGroups.nonBananas"> <mat-card [fruit]="fruit"></mat-card> </div> <!-- Bananas --> <div *ngFor="let fruit of fruitGroups.bananas"> <mat-card [fruit]="fruit"></mat-card> </div> </div>
这种写法既解决了空div问题,又只遍历一次原数组,性能更优。
内容的提问来源于stack exchange,提问作者PaulBunion
相关产品推荐
相关产品推荐

