Angular条件渲染实现:按角色分模块展示人员且不重复模板
复用模板实现多角色人员展示方案
核心思路
将重复的人员列表模板抽成通用Angular组件,通过输入属性传递不同角色的标题、数据、类型标识及相关方法,实现同一模板复用展示SPEAKER、MODERATOR、ORGANIZER三类人员。
1. 创建通用人员列表组件
组件类代码(person-list.component.ts)
import { Component, Input } from '@angular/core'; import { MatMenu } from '@angular/material/menu'; // 建议定义人员数据接口替代any,示例: // interface Person { // image?: string; // first_name?: string; // last_name?: string; // AppUser?: { image?: string; first_name?: string; last_name?: string }; // myLike: number; // likesCount: number; // commentsCount: number; // } @Component({ selector: 'app-person-list', templateUrl: './person-list.component.html', styleUrls: ['./person-list.component.css'] }) export class PersonListComponent { @Input() title!: string; // 列表标题(如Speakers/Moderators) @Input() people!: any[]; // 对应角色的人员数据数组 @Input() roleType!: 'speaker' | 'moderator' | 'organizer'; // 角色类型标识 @Input() likeMapping!: Record<string, string>; // 复数映射配置 @Input() commentMapping!: Record<string, string>; @Input() loading!: boolean; // 通用方法/实例传入 @Input() generateAvatar!: (image: string | undefined, name: string | undefined) => string; @Input() likePerson!: (person: any, role: string) => void; @Input() viewComments!: (person: any) => void; @Input() attendeeMenu!: MatMenu; // 操作菜单实例 }
组件模板代码(person-list.component.html)
<mat-list *ngIf="!loading"> <div *ngIf="people.length > 0"> <div mat-subheader>{{ title }}</div> <mat-list-item *ngFor="let person of people"> <img default="default" matListAvatar [src]="generateAvatar(person?.image || person?.AppUser?.image, person?.first_name || person?.AppUser?.first_name)" alt="人员头像" /> <div mat-line style="display: flex;"> <div class="fill-remaining-space"> <div class="overflow"> {{ (person?.first_name || person?.AppUser?.first_name || "") + " " + (person?.last_name || person?.AppUser?.last_name || "~Anonymous") | titlecase }} </div> <div class="like-comment-section"> <app-like-btn (click)="likePerson(person, roleType)" [liked]="person.myLike > 0" ></app-like-btn> <span class="like-text">{{ person.likesCount | i18nPlural : likeMapping }}</span> <span (click)="viewComments(person)" class="comment-section"> <i class="ui comments icon"></i> </span> <span (click)="viewComments(person)" class="comment-text"> {{ person.commentsCount | i18nPlural : commentMapping }} </span> </div> </div> <div> <button [matMenuTriggerData]="{ speaker: person, attendee: person?.AppUser, type: roleType }" mat-icon-button [matMenuTriggerFor]="attendeeMenu" aria-label="操作菜单" > <mat-icon>more_vert</mat-icon> </button> </div> </div> </mat-list-item> </div> </mat-list>
2. 父组件中复用通用组件
在需要展示多角色人员的父组件模板中,分别调用通用组件并传入对应角色的参数:
<!-- 展示演讲者(SPEAKER) --> <app-person-list title="Speakers" [people]="speakers" roleType="speaker" [likeMapping]="likeMapping" [commentMapping]="commentMapping" [loading]="loading" [generateAvatar]="generateAvatar" [likePerson]="likePerson" [viewComments]="viewSpeakerComments" [attendeeMenu]="attendeeMenu" ></app-person-list> <!-- 展示主持人(MODERATOR) --> <app-person-list title="Moderators" [people]="moderators" roleType="moderator" [likeMapping]="likeMapping" [commentMapping]="commentMapping" [loading]="loading" [generateAvatar]="generateAvatar" [likePerson]="likePerson" [viewComments]="viewModeratorComments" [attendeeMenu]="attendeeMenu" ></app-person-list> <!-- 展示组织者(ORGANIZER) --> <app-person-list title="Organizers" [people]="organizers" roleType="organizer" [likeMapping]="likeMapping" [commentMapping]="commentMapping" [loading]="loading" [generateAvatar]="generateAvatar" [likePerson]="likePerson" [viewComments]="viewOrganizerComments" [attendeeMenu]="attendeeMenu" ></app-person-list>
关键说明
- 若不同角色的评论、点赞逻辑完全一致,可复用同一个
viewComments/likePerson方法,无需单独定义。 - 建议为人员数据创建TypeScript接口,替换代码中的
any类型,提升代码规范性和可维护性。
内容的提问来源于stack exchange,提问作者tarus
相关产品推荐
相关产品推荐

