Issue
How to hide element if ng-content not exists in Angular?
<mat-card>
<mat-card-header #title *ngIf="title"> <-- title
<mat-card-title>
<ng-content select="[title]"></ng-content>
</mat-card-title>
</mat-card-header>
<mat-divider *ngIf="title"></mat-divider>
<mat-card-content>
<ng-content select="[content]"></ng-content>
</mat-card-content>
</mat-card>
if ng-container title not exists, then hiding mat-card-header in the component above
<card>
<ng-container title>
title
</ng-container>
<ng-container content>
....
</ng-container>
</card>
@Component({
selector: 'card',
templateUrl: './card.component.html',
styleUrls: ['./card.component.scss']
})
export class CardComponent implements OnInit {
@ViewChild('title', {static: true}) titleRef: ElementRef;
title = true;
// contentExists = true;
constructor() {
}
ngOnInit(): void {
if ((this.titleRef.nativeElement.innerHTML ?? '').trim() === '') {
this.title = false;
}
TS logic
Solution
This should be moved to NgAfterViewInit cycle as element ref's can be access at the earliest in the cycle.
ngAfterViewInit(): void {
if ((this.titleRef.nativeElement.innerHTML ?? '').trim() === '') {
this.title = false;
}
I don't see the whole context in you example but I wouldn't add unnecessary TS code (the @ViewChild) just to get one boolean. This could all be done in template.
Keep in mind, that when template is being rendered it's being rendered from highest layer parent -> child.
Now if we change the template parent based on some child layer result (e.g ng-content result will remove mat-card) then we will start getting Expression has changed errors, because template itself changed (mat-card got removed before the whole rendering cycle finished). Make sure to start rendering stuff from parent -> child, not going backwards at any point.
- First find if
mat-cardit worth being rendered at all? - Then if the
titleshould be rendered. - Then if the
contentshould be rendered and so on...
<mat-card *ngIf="item">
<ng-container *ngIf="title">
<mat-card-header #title>
<mat-card-title>
<ng-content select="[title]"></ng-content>
</mat-card-title>
</mat-card-header>
<mat-divider></mat-divider>
</ng-container>
<mat-card-content *ngIf="content">
<ng-content select="[content]"></ng-content>
</mat-card-content>
</mat-card>
Answered By - Joosep Parts
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.