// counter.component.ts import { Component, Input, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-counter', standalone: true, template: `

Child count: {{ count }}

`, }) export class CounterComponent { @Input() count = 0; @Output() countChange = new EventEmitter(); increment() { this.countChange.emit(this.count + 1); } decrement() { this.countChange.emit(this.count - 1); } } // app.component.ts import { Component } from '@angular/core'; import { CounterComponent } from './counter/counter.component'; @Component({ selector: 'app-root', standalone: true, imports: [CounterComponent], template: `

Parent total: {{ total }}

`, }) export class AppComponent { total = 0; } /* Notes: - The pairing of @Input() count and @Output() countChange (the input name + "Change") is what unlocks the [(count)] two-way syntax in the parent — this is exactly how [(ngModel)] works internally. - The child never reassigns count directly; it emits the new value via countChange, and Angular's two-way binding writes that back into the parent's `total`, which then flows back down as the new count. Both "Child count" and "Parent total" always stay in sync. */