In the traditional Angular approach, creating two-way binding meant setting up both an @Input() to receive data and an @Output() to emit changes. You also needed to wire up event emitters manually. This pattern worked, but it added boilerplate and split the logic for incoming and outgoing data.
What model() Signal Does Differently
Introduced in Angular v17, the model() signal replaces the old binding setup with a single, writable signal. This signal acts both as an input and an output. When the parent updates the bound property, the signal gets updated. When the child sets a new value, that change automatically reflects back in the parent.
Comparing Old vs. New in a Real Example
Old Way Using @Input() and @Output()
@Component({ selector: 'app-custom-input-old', template: `<input [value]="value" (input)="onValueChange($event)">`
})
export class CustomInputOldComponent { @Input() value: string = ''; @Output() valueChange = new EventEmitter<string>(); onValueChange(event: Event) { const target = event.target as HTMLInputElement; this.valueChange.emit(target.value); }
}
Usage:
<app-custom-input-old [(value)]="parentProperty"></app-custom-input-old>
New Way Using model()
@Component({ selector: 'app-custom-input-new', standalone: true, template: `<input [value]="value()" (input)="onValueChange($event)">`
})
export class CustomInputNewComponent { value = model.required<string>(); onValueChange(event: Event) { const target = event.target as HTMLInputElement; this.value.set(target.value); }
}
Usage:
<app-custom-input-new [(value)]="parentProperty"></app-custom-input-new>
Why model() Improves Component Design
- Less Code, Fewer Mistakes
You define the binding in one place. No need for extra decorators or emitters. - Cleaner State Management
The writable signal makes it clear where state comes from and where it goes. - Reactive by Nature
Since it’s a signal, you can hook into changes with computed() or effect() without extra wiring.
Conclusion
The model() signal simplifies two-way binding into a single, readable, and reactive property. It cuts boilerplate, unifies component state, and improves maintainability. If you’re serious about building modern Angular apps with cleaner architecture and fewer moving parts, it’s time to embrace signals. And if you want expert help modernizing your codebase, hire Angular developers who already work with signals and understand how to architect with model() at the core. It’ll save you time, money, and future headaches.