javascript / expert
Snippet
Two-Way Binding Contracts with model()
The model() function creates a writable signal that automatically generates both an input and an output, enabling two-way binding syntax [(value)] without manually wiring an @Input/@Output pair. Internally Angular synthesizes a 'valueChange' output that fires whenever the signal is set, so parent components stay in sync without RxJS subjects or manual emit calls. This collapses boilerplate that previously required a getter/setter pair or an @Output EventEmitter, while keeping the component's internal state as a genuine signal usable in computed() and effect().
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { Component, model } from '@angular/core';@Component({selector: 'app-rating',standalone: true,template: `<button*ngFor="let star of stars"(click)="setValue(star)"[class.filled]="star <= value()">★</button>`,})export class RatingComponent {value = model<number>(0);readonly stars = [1, 2, 3, 4, 5];setValue(star: number): void {if (star === this.value()) {this.value.set(0);return;}this.value.set(star);}}// Parent usage: <app-rating [(value)]="userRating" />
angular
Breakdown
1
value = model<number>(0);
Declares a writable model signal with default 0; Angular auto-generates a paired 'value' input and 'valueChange' output.
2
this.value.set(0);
Setting the signal directly triggers the synthesized output emission, propagating the change upward to any [(value)] binding.
3
[class.filled]="star <= value()"
Reading value() in the template creates a reactive dependency, so the star highlighting updates whenever the model changes from either direction.