0 Tage Serie
javascript / expert
Snippet

Zweiseitige Bindungsverträge mit model()

Die Funktion model() erzeugt ein beschreibbares Signal, das automatisch sowohl einen Input als auch einen Output erzeugt und damit die Zwei-Wege-Bindungssyntax [(value)] ermöglicht, ohne manuell ein @Input/@Output-Paar zu verdrahten. Intern generiert Angular einen 'valueChange'-Output, der bei jedem Setzen des Signals feuert, sodass Elternkomponenten ohne RxJS-Subjects oder manuelle emit-Aufrufe synchron bleiben. Das reduziert Boilerplate, die früher ein Getter/Setter-Paar oder einen @Output EventEmitter erforderte, während der interne Zustand der Komponente ein echtes Signal bleibt, das in computed() und effect() nutzbar ist.

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
Erklärung
1
value = model<number>(0);
Deklariert ein beschreibbares Model-Signal mit Standardwert 0; Angular generiert automatisch einen gekoppelten 'value'-Input und 'valueChange'-Output.
2
this.value.set(0);
Das direkte Setzen des Signals löst die synthetisierte Output-Emission aus und propagiert die Änderung nach oben an jede [(value)]-Bindung.
3
[class.filled]="star <= value()"
Das Lesen von value() im Template erzeugt eine reaktive Abhängigkeit, sodass die Sternmarkierung bei jeder Änderung des Models aktualisiert wird.