You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: adev/src/content/guide/forms/reactive-forms.md
+102Lines changed: 102 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -388,6 +388,108 @@ Initially, the form contains one `Alias` field. To add another field, click the
388
388
389
389
</docs-workflow>
390
390
391
+
## Unified control state change events
392
+
393
+
All form controls expose a single unified stream of **control state change events** through the `events` observable on `AbstractControl` (`FormControl`, `FormGroup`, `FormArray`, and `FormRecord`).
394
+
This unified stream lets you react to **value**, **status**, **pristine**, **touched** and **reset** state changes and also for **form-level actions** such as **submit** , allowing you to handle all updates with a one subscription instead of wiring multiple observables.
395
+
396
+
### Event types
397
+
398
+
Each item emitted by `events` is an instance of a specific event class:
399
+
400
+
-**`ValueChangeEvent`** — when the control’s **value** changes.
401
+
-**`StatusChangeEvent`** — when the control’s **validation status** updates to one of the `FormControlStatus` values (`VALID`, `INVALID`, `PENDING`, or `DISABLED`).
402
+
-**`PristineChangeEvent`** — when the control’s **pristine/dirty** state changes.
403
+
-**`TouchedChangeEvent`** — when the control’s **touched/untouched** state changes.
404
+
-**`FormResetEvent`** — when a control or form is reset, either via the `reset()` API or a native action.
405
+
-**`FormSubmittedEvent`** — when the form is submitted.
406
+
407
+
All event classes extend `ControlEvent` and include a `source` reference to the `AbstractControl` that originated the change, which is useful in large forms.
408
+
409
+
```ts
410
+
import { Component } from'@angular/core';
411
+
import {
412
+
FormControl,
413
+
ValueChangeEvent,
414
+
StatusChangeEvent,
415
+
PristineChangeEvent,
416
+
TouchedChangeEvent,
417
+
FormResetEvent,
418
+
FormSubmittedEvent,
419
+
ReactiveFormsModule,
420
+
FormGroup,
421
+
} from'@angular/forms';
422
+
423
+
@Component({/* ... */ })
424
+
exportclassUnifiedEventsBasicComponent {
425
+
form =newFormGroup({
426
+
username: newFormControl(''),
427
+
});
428
+
429
+
constructor() {
430
+
this.form.events.subscribe((e) => {
431
+
if (einstanceofValueChangeEvent) {
432
+
console.log('Value changed to: ', e.value);
433
+
}
434
+
435
+
if (einstanceofStatusChangeEvent) {
436
+
console.log('Status changed to: ', e.status);
437
+
}
438
+
439
+
if (einstanceofPristineChangeEvent) {
440
+
console.log('Pristine status changed to: ', e.pristine);
441
+
}
442
+
443
+
if (einstanceofTouchedChangeEvent) {
444
+
console.log('Touched status changed to: ', e.touched);
445
+
}
446
+
447
+
if (einstanceofFormResetEvent) {
448
+
console.log('Form was reset');
449
+
}
450
+
451
+
if (einstanceofFormSubmittedEvent) {
452
+
console.log('Form was submitted');
453
+
}
454
+
});
455
+
}
456
+
}
457
+
```
458
+
459
+
### Filtering specific events
460
+
461
+
Prefer RxJS operators when you only need a subset of event types.
// Handle ValueChangeEvent, StatusChangeEvent, etc.
488
+
});
489
+
```
490
+
491
+
NOTE: On value change, the emit happens right after a value of this control is updated. The value of a parent control (for example if this FormControl is a part of a FormGroup) is updated later, so accessing a value of a parent control (using the `value` property) from the callback of this event might result in getting a value that has not been updated yet. Subscribe to the `events` of the parent control instead.
492
+
391
493
## Reactive forms API summary
392
494
393
495
The following table lists the base classes and services used to create and manage reactive form controls.
0 commit comments