Angular 2中*ngFor循环下@Output子组件传值异常求助
Hey there! This is a super common pitfall when working with *ngFor and child components in Angular, so let's walk through the most likely issues and how to fix them.
1. You're not passing the child's unique value via the @Output event
The most frequent cause is that your child component isn't emitting its specific instance value, or your parent isn't capturing the emitted value correctly.
Wrong Approach:
Child Component (relies on a potentially shared variable instead of its own input):
import { Component, Input, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-child', template: `<button (click)="sendValue()">Send Value</button>` }) export class ChildComponent { @Input() item: any; @Output() valueChanged = new EventEmitter<any>(); // Risky: this variable might get overwritten if state isn't isolated tempValue: any; ngOnInit() { this.tempValue = this.item; } sendValue() { this.valueChanged.emit(this.tempValue); } }
Parent Component (doesn't use the emitted $event):
<div *ngFor="let item of items"> <app-child [item]="item" (valueChanged)="handleValueChange()"></app-child> </div>
// Parent component class export class ParentComponent { currentValue: any; handleValueChange() { // If this was set by the first child, it won't update for others console.log(this.currentValue); } }
Correct Approach:
Child Component (emit its own input value directly):
import { Component, Input, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-child', template: `<button (click)="sendValue()">Send Value</button>` }) export class ChildComponent { @Input() item: any; @Output() valueChanged = new EventEmitter<any>(); sendValue() { // Emit the unique value tied to this child instance this.valueChanged.emit(this.item); } }
Parent Component (use $event to capture the exact emitted value):
<div *ngFor="let item of items"> <app-child [item]="item" (valueChanged)="handleValueChange($event)"></app-child> </div>
// Parent component class export class ParentComponent { handleValueChange(childValue: any) { // Now you get the value from the exact child that triggered the event console.log(childValue); } }
2. You're using a duplicate template reference variable
If you added a template variable like #child to every child component in the *ngFor loop, Angular will only reference one instance (usually the first or last rendered component) instead of the one that triggered the event.
Wrong:
<div *ngFor="let item of items"> <!-- All children share the same #child variable --> <app-child #child [item]="item" (valueChanged)="handleValueChange(child.item)"></app-child> </div>
Correct:
Skip the template variable for this scenario. The $event approach from the first section is far more reliable—it explicitly ties the event to the triggering child's value.
3. You're using static variables in the child component
Static variables in the child component are shared across all instances, so all children will emit the same (often the first assigned) value.
Wrong:
export class ChildComponent { @Input() item: any; @Output() valueChanged = new EventEmitter<any>(); // Static = shared across every child instance static sharedItem: any; ngOnInit() { ChildComponent.sharedItem = this.item; } sendValue() { this.valueChanged.emit(ChildComponent.sharedItem); } }
Correct:
Use instance-level variables so each child maintains its own state:
export class ChildComponent { @Input() item: any; @Output() valueChanged = new EventEmitter<any>(); sendValue() { this.valueChanged.emit(this.item); } }
Quick Recap
- Always emit the child's unique instance value via
@Output - Capture the emitted value in the parent using
$event - Avoid duplicate template variables or static variables that cause shared state
内容的提问来源于stack exchange,提问作者Girish Mahida

