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

Angular 15子组件无法向父组件emit字符串问题排查

Angular 15子组件向父组件传值失效问题解决

问题场景

在Angular 15项目中,尝试从子组件filters.component.ts向父组件home.component.ts传递字符串。此前在其他组件实现过相同逻辑,但使用*ngFor遍历字符串数组并传递category字符串到方法时出现异常:点击按钮触发事件后,父组件home.component.ts中的onShowCategory()方法未执行(添加console.log无输出),页面也无法显示选中的category值。

相关代码

filters.component.html

<mat-expansion-panel *ngIf="categories">
    <mat-expansion-panel-header>
        <mat-panel-title>CATEGORIES</mat-panel-title>
    </mat-expansion-panel-header>
    <mat-selection-list [multiple]="false">
        <mat-list-option *ngFor="let category of categories" [value]="category">
            <button (click)="onShowCategory(category)">{{ category }}</button>
        </mat-list-option>
    </mat-selection-list>
</mat-expansion-panel>

filters.component.ts

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

@Component({
  selector: 'app-filters',
  templateUrl: './filters.component.html',
  styleUrls: []
})
export class FiltersComponent {
  @Output() showCategory = new EventEmitter<string>()

  categories: string[] = ['shoes', 'sports'];

  onShowCategory(category: string): void {
    this.showCategory.emit(category);
  }
}

home.component.html

<mat-drawer-container [autosize]="true" class="min-h-full max-w-7xl mx-auto border-x">
    <mat-drawer mode="side" class="p-6" opened>
        <app-filters (showCategory)="onShowCategory($event)"></app-filters>
    </mat-drawer>
    
    <mat-drawer-content class="p-6">
        <app-products-header (columnsCountChange)="onColumnsCountChange($event)"></app-products-header>
        
        {{ category }} <!-- 选中后应显示的category -->
    </mat-drawer-content>
</mat-drawer-container>

home.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: []
})
export class HomeComponent {
  cols = 3;
  category: string | undefined;
  
  onColumnsCountChange(colsNumber: number): void {
    this.cols = colsNumber
  }
 
  onShowCategory(newCategory: string): void {
    this.category = newCategory;
  }
}

问题根源

问题出在mat-list-option的默认行为上:当点击它内部的按钮时,mat-list-option会优先触发自身的选中逻辑,并且自动阻止了按钮点击事件的冒泡传递,导致你绑定的(click)事件根本无法触发,自然也就不会执行onShowCategory方法和发射事件。

解决方案

方案1:阻止按钮事件冒泡

直接修改按钮的点击绑定,添加$event.stopPropagation()来阻止事件向上传递给mat-list-option:

<button (click)="onShowCategory(category); $event.stopPropagation()">{{ category }}</button>

方案2:使用mat-selection-list自带的选中事件(推荐)

既然用了Material的选择列表组件,直接利用它原生的selectionChange事件更符合组件设计逻辑,还能去掉多余的按钮:

  1. 修改filters.component.html:
<mat-selection-list [multiple]="false" (selectionChange)="onCategorySelected($event)">
  <mat-list-option *ngFor="let category of categories" [value]="category">
    {{ category }}
  </mat-list-option>
</mat-selection-list>
  1. 修改filters.component.ts的方法(记得导入对应的类型):
import { MatSelectionListChange } from '@angular/material/list';

// ...

onCategorySelected(event: MatSelectionListChange): void {
  this.showCategory.emit(event.option.value);
}

方案3:移除mat-list-option(若不需要选择高亮特性)

如果不需要Material选择列表的选中高亮等特性,直接用普通列表包裹按钮即可:

<ul>
  <li *ngFor="let category of categories">
    <button (click)="onShowCategory(category)">{{ category }}</button>
  </li>
</ul>

验证

采用任意一种方案后,点击分类选项时,父组件的onShowCategory方法会正常执行,页面也能正确显示选中的category值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:40:18