You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现支持单选的mat-card列表组件并向父组件传递选中项标识

Angular 单选卡片列表组件实现方案

你提到用到mat-card,默认基于Angular + Angular Material技术栈实现,步骤如下:

核心逻辑

选中状态统一托管给列表容器组件,单选切换逻辑由容器处理,对外暴露选中ID供父组件读取,每个卡片仅负责接收选中状态、触发选择事件。

分步实现

1. 定义可选中卡片组件(可选,也可直接用原生mat-card)

如果需要统一卡片的选中样式和交互,先封装通用子组件selectable-card:

组件TS代码

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-selectable-card',
  templateUrl: './selectable-card.component.html',
  styleUrls: ['./selectable-card.component.css']
})
export class SelectableCardComponent {
  // 卡片唯一标识,用业务ID即可
  @Input() itemId: string | number;
  // 接收当前是否选中的状态
  @Input() isSelected: boolean;
  // 点击时向外抛出选中的ID
  @Output() selectCard = new EventEmitter<string | number>();
}

组件模板代码

<mat-card 
  [class.selected]="isSelected" 
  (click)="selectCard.emit(itemId)"
>
  <!-- 插槽,支持自定义卡片内容 -->
  <ng-content></ng-content>
</mat-card>

组件样式代码

mat-card {
  cursor: pointer;
  transition: all 0.2s ease;
  margin-bottom: 12px;
}
/* 选中状态样式,可自行调整 */
mat-card.selected {
  background-color: #e0f2fe;
  border: 2px solid #0284c7;
  box-shadow: 0 4px 12px rgba(2, 132, 199, 0.15);
}

2. 实现卡片列表容器组件

封装列表组件统一处理单选逻辑:

组件TS代码

import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-card-list',
  templateUrl: './card-list.component.html',
  styleUrls: ['./card-list.component.css']
})
export class CardListComponent {
  // 当前选中的ID,支持双向绑定
  @Input() selectedId: string | number | null = null;
  @Output() selectedIdChange = new EventEmitter<string | number>();

  // 处理卡片选中事件
  handleCardSelect(id: string | number) {
    // 单选逻辑:直接替换当前选中ID
    this.selectedId = id;
    this.selectedIdChange.emit(id);
  }
}

组件模板代码

<div class="card-list">
  <!-- 插槽,支持放入任意数量的卡片 -->
  <ng-content></ng-content>
</div>

3. 父组件中调用

父组件可以直接读取、绑定选中的ID:

父组件TS代码

// 定义你的卡片列表数据
cardList = [
  {id: 1, title: '卡片1', content: '卡片1内容'},
  {id: 2, title: '卡片2', content: '卡片2内容'},
  {id: 3, title: '卡片3', content: '卡片3内容'},
]
// 绑定当前选中ID
currentSelectedId: number | null = null;

父组件模板代码

<!-- 用双向绑定直接拿到选中值 -->
<app-card-list [(selectedId)]="currentSelectedId">
  <!-- 循环渲染卡片 -->
  <app-selectable-card 
    *ngFor="let card of cardList"
    [itemId]="card.id"
    [isSelected]="currentSelectedId === card.id"
    (selectCard)="$event && handleCardSelect($event)"
  >
    <!-- 自定义卡片内容 -->
    <mat-card-header>
      <mat-card-title>{{card.title}}</mat-card-title>
    </mat-card-header>
    <mat-card-content>
      <p>{{card.content}}</p>
    </mat-card-content>
  </app-selectable-card>
</app-card-list>

<p>当前选中的卡片ID:{{currentSelectedId}}</p>

更优简化实现

如果不想封装太多组件,可以直接用Angular CDK自带的SelectionModel实现单选逻辑,代码量更少,稳定性更高:

  1. 导入依赖:import { SelectionModel } from '@angular/cdk/collections';
  2. 初始化单选实例:selection = new SelectionModel<number>(false, []); 第一个参数false代表单选模式
  3. 模板中直接绑定状态:
<mat-card 
  *ngFor="let card of cardList"
  [class.selected]="selection.isSelected(card.id)"
  (click)="selection.select(card.id)"
>
  <!-- 卡片内容 -->
</mat-card>
<p>当前选中的ID:{{selection.selected[0]}}</p>

选中样式和之前的实现一致,不需要额外写单选切换逻辑,CDK已经内置了所有选中、取消选中的处理。


内容的提问来源于stack exchange,提问作者Awybin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 09:57:03