Let's say I have this list of people I want to display. Below you'll see the HTML for this iteration in a *ngFor loop. You can view this StackBlitz to check out the full example.
<mat-list role="list">
<mat-list-item *ngFor="let name of names" role="listitem">
<mat-icon mat-list-icon>person</mat-icon>
<h4 mat-line>{{name.firstName}}</h4>
</mat-list-item>
</mat-list>
In some cases the list should be displayed as a linked list, since the list of people then link to other webpages. What I could do to achieve this is to write an *ngIf that checks if it should be a linked list or a normal list, as written below.
<div *ngIf="isNormalList; else isLinkedList">
<h3>Normal list with items</h3>
<mat-list role="list">
<mat-list-item *ngFor="let name of names" role="listitem">
<mat-icon mat-list-icon>person</mat-icon>
<h4 mat-line>{{name.firstName}}</h4>
</mat-list-item>
</mat-list>
</div>
<ng-template #isLinkedList>
<h3>List with clickable items</h3>
<mat-list role="list">
<a mat-list-item href="#" *ngFor="let name of names" role="listitem">
<mat-icon mat-list-icon>person</mat-icon>
<h4 mat-line>{{name.firstName}}</h4>
</a>
</mat-list>
</ng-template>
However, solving it this way seems like a lot of duplicate code. I could also write an *ngIf for the inner part of the list item, but that is more or less the same and ends up in duplicate code as well.
Is there a way to only add the a element conditionally within this setup?
Something like this should work. I think you can ease the context bit when using $implicit to make it shorter, but not sure how exactly, you can check the Angular docs.
On a side note, I don't think you need to specify the role attributes, Material should provide these for you.
<div>
<mat-list role="list">
<ng-container *ngIf="isNormalList; else isLinkedList">
<mat-list-item *ngFor="let name of names" role="listitem">
<ng-container *ngTemplateOutlet="listItem; context: { $implicit: name }"></ng-container>
</mat-list-item>
</ng-container>
<ng-template #isLinkedList>
<a mat-list-item href="#" *ngFor="let name of names" role="listitem">
<ng-container *ngTemplateOutlet="listItem; context: { $implicit: name }"></ng-container>
</a>
</ng-template>
</mat-list>
</div>
<ng-template #listItem let-name>
<mat-icon mat-list-icon>person</mat-icon>
<h4 mat-line>{{name.firstName}}</h4>
</ng-template>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With