Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Sichere ProgrammierungKI half beim Finden: iOS 27 schließt mehr als 100 Sicherheitslücken(21.09.2026 um 06:00 Uhr)
Sichere ProgrammierungWhat Is Rowhammer? How Can Repeated Memory Access Flip Bits in RAM?(21.09.2026 um 07:12 Uhr)
Sichere Programmierungnpm publish Ignores .gitignore: The .npmignore Override Rule(21.09.2026 um 07:15 Uhr)
Sichere ProgrammierungAphelion Editor - A free node-based video / VFX editor(21.09.2026 um 07:21 Uhr)
Sichere ProgrammierungGovernance Attack Surface Review: OKX(21.09.2026 um 07:31 Uhr)
Sichere ProgrammierungJSM Portal Request Create Property Panel Submit(21.09.2026 um 07:34 Uhr)
Reverse Engineeringsearch instructions assembly easy (X86,RISCV,AARCH64,etc)(20.09.2026 um 15:44 Uhr)
Sichere ProgrammierungKI half beim Finden: iOS 27 schließt mehr als 100 Sicherheitslücken(21.09.2026 um 06:00 Uhr)
Sichere ProgrammierungWhat Is Rowhammer? How Can Repeated Memory Access Flip Bits in RAM?(21.09.2026 um 07:12 Uhr)
Sichere Programmierungnpm publish Ignores .gitignore: The .npmignore Override Rule(21.09.2026 um 07:15 Uhr)
Sichere ProgrammierungAphelion Editor - A free node-based video / VFX editor(21.09.2026 um 07:21 Uhr)
Sichere ProgrammierungGovernance Attack Surface Review: OKX(21.09.2026 um 07:31 Uhr)
Sichere ProgrammierungJSM Portal Request Create Property Panel Submit(21.09.2026 um 07:34 Uhr)
Reverse Engineeringsearch instructions assembly easy (X86,RISCV,AARCH64,etc)(20.09.2026 um 15:44 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Mastering Angular ControlValueAccessor (CVA): The Complete Guide with Real-World Examples

Reagiere als Erste:r — dein Feedback zählt!

Angular provides many built-in form controls such as <input>, <textarea>, <select>, and checkboxes. These elements work seamlessly with both Template-driven Forms and Reactive Forms because Angular already knows how to communicate with them.

But what happens when you build your own reusable component?

Imagine creating:

  • A star rating component ⭐
  • A color picker 🎨
  • A date range selector 📅
  • A phone number input 📞
  • A rich text editor ✍️

By default, Angular has no idea how these components should exchange values with a form.

This is exactly why ControlValueAccessor (CVA) exists.

What is ControlValueAccessor?
ControlValueAccessor is an Angular interface that acts as a bridge between:

  • Angular Forms API
  • Your custom component

It teaches Angular how to:

  • Write values into your component
  • Read values from your component
  • Mark the component as touched
  • Enable or disable the component

Without CVA, Angular treats your component as just another HTML element.

With CVA, Angular treats it exactly like a native <input>.

Think of CVA Like a Translator

Imagine two people speaking different languages.

  • Angular Forms speaks one language.
  • Your custom component speaks another.

ControlValueAccessor translates between them.

Reactive Form
      |
      |
ControlValueAccessor
      |
      |
Custom Component

Why Do We Need It?
Suppose you build this component:
<app-counter></app-counter>

<form [formGroup]="form">

    <app-counter formControlName="quantity"></app-counter>

</form>

Angular immediately throws an error:
No value accessor for form control with name: 'quantity'

Why?

Because Angular doesn't know:

  • How to pass the value
  • How to receive updates
  • When the control becomes touched
  • How to disable it

CVA solves all of this.

The ControlValueAccessor Interface
The interface looks like this:

export interface ControlValueAccessor {

    writeValue(obj: any): void;

    registerOnChange(fn: any): void;

    registerOnTouched(fn: any): void;

    setDisabledState?(isDisabled: boolean): void;

}

Only four methods.

But each has an important responsibility.

Method 1 — writeValue()
Angular calls this whenever the form value changes.

Example:

this.form.patchValue({
    quantity: 10
});

Angular internally executes:
component.writeValue(10);

Your implementation:

writeValue(value: number): void {
    this.value = value;
}

Think of it as:
Form ➜ Component

Method 2 — registerOnChange()
Angular gives you a callback function.

Whenever your component value changes, you must call it.

registerOnChange(fn: any): void {
    this.onChange = fn;
}

Later:

increment() {
    this.value++;
    this.onChange(this.value);
}

Flow:

User Clicks
      ↓
Component Updates
      ↓
onChange(value)
      ↓
Angular Form Updates

Think of it as:
Component ➜ Form

Method 3 — registerOnTouched()
Angular also provides another callback.

This tells Angular that the user interacted with the control.

registerOnTouched(fn: any): void {
    this.onTouched = fn;
}

When should you call it?

Usually on:

  • blur
  • click
  • focus lost
  • first interaction

Example:

onBlur() {
    this.onTouched();
}

Now Angular knows:
control.touched === true

Method 4 — setDisabledState()
When someone writes:

control.disable();

Angular calls:

setDisabledState(true);

Implementation

setDisabledState(isDisabled: boolean): void {
    this.disabled = isDisabled;
}

Then your template:
<button [disabled]="disabled">
Now disabling works exactly like native inputs.

The Data Flow

Form.setValue()
        |
        |
writeValue()
        |
        |
Custom Component
        |
User Interaction
        |
        |
onChange()
        |
        |
Reactive Form

A Complete Counter Component
counter.component.ts

import {
    Component,
    forwardRef
} from '@angular/core';

import {
    ControlValueAccessor,
    NG_VALUE_ACCESSOR
} from '@angular/forms';

@Component({
    selector: 'app-counter',

    templateUrl: './counter.component.html',

    providers: [
        {
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(() => CounterComponent),
            multi: true
        }
    ]
})
export class CounterComponent implements ControlValueAccessor {

    value = 0;

    disabled = false;

    onChange = (_: number) => {};

    onTouched = () => {};

    writeValue(value: number): void {
        this.value = value ?? 0;
    }

    registerOnChange(fn: any): void {
        this.onChange = fn;
    }

    registerOnTouched(fn: any): void {
        this.onTouched = fn;
    }

    setDisabledState(isDisabled: boolean): void {
        this.disabled = isDisabled;
    }

    increment() {
        if (this.disabled) return;

        this.value++;

        this.onChange(this.value);

        this.onTouched();
    }

    decrement() {
        if (this.disabled) return;

        this.value--;

        this.onChange(this.value);

        this.onTouched();
    }

}

counter.component.html

<button (click)="decrement()" [disabled]="disabled">
    -
</button>

<span>{{ value }}</span>

<button (click)="increment()" [disabled]="disabled">
    +
</button>

Parent Component

form = this.fb.group({

    quantity: [5]

});
<form [formGroup]="form">

    <app-counter formControlName="quantity"></app-counter>

</form>

Everything now works exactly like:
<input formControlName="quantity">

Understanding the Lifecycle
When the page loads:

Angular Creates Component
        ↓
registerOnChange()
        ↓
registerOnTouched()
        ↓
writeValue(initialValue)

When the user clicks "+" :

value++
      ↓
onChange(value)
      ↓
FormControl Updated

When the form resets:

form.reset()
      ↓
writeValue(null)
      ↓
Component Updated

When disabled:

control.disable()
       ↓
setDisabledState(true)

Common Mistakes

Mistake #1

Changing the value without calling onChange

Wrong:
this.value++;

Correct:

this.value++;

this.onChange(this.value);

Mistake #2
Never calling onTouched

Wrong:

click() {
    this.value++;
}

Correct:

click() {

    this.value++;

    this.onTouched();

}

Mistake #3
Ignoring disabled state

Wrong

increment() {

    this.value++;

}

Correct:
if (this.disabled) return;

Mistake #4
Forgetting NG_VALUE_ACCESSOR

Without:

providers: [
    ...
]

Angular cannot discover your accessor.

CVA with Validators

CVA only handles value communication.

Validation is separate.

You can still use:

Validators.required

Validators.min(1)

Validators.max(10)

Example:

quantity: new FormControl(
    1,
    Validators.min(1)
)

Angular validates normally.

CVA + Signals (Angular 17+)
Instead of:
value = 0;

You can use:
value = signal(0);

Writing value:

writeValue(value: number) {
    this.value.set(value);
}

Updating:

increment() {

    this.value.update(v => v + 1);

    this.onChange(this.value());

}

Signals work perfectly with CVA and make state updates more declarative.

Real-World Components That Use CVA
Almost every reusable form component benefits from implementing ControlValueAccessor:

  • Custom dropdowns
  • Searchable selects
  • Multi-select components
  • Tag inputs
  • Date pickers
  • Time pickers
  • Color pickers
  • File uploaders
  • Phone number inputs
  • OTP inputs
  • Rich text editors
  • Sliders
  • Range selectors
  • Rating components
  • Toggle switches
  • Tree selectors
  • Custom checkboxes
  • Custom radio buttons
  • Markdown editors

Best Practices

  • Keep writeValue() free of side effects; update internal state only.
  • Always call onChange()when the value changes due to user interaction, not when writeValue() is invoked by Angular.
  • CallonTouched() when the user has meaningfully interacted with the control (often on blur, sometimes on the first interaction depending on the UX).
  • Respect the disabled state in both your component logic and template.
  • Expose a single source of truth for the value to avoid synchronization bugs.
  • Combine CVA with OnPushchange detection or Signals for better performance in reusable components.
  • Make your component accessible by supporting keyboard navigation, focus management, and ARIA attributes.

Final Thoughts
ControlValueAccessor is one of the most important APIs for building professional Angular applications. It allows your custom components to integrate seamlessly with Angular Forms, making them behave exactly like native form controls. By correctly implementing writeValue(), registerOnChange(), registerOnTouched(), and setDisabledState(), you unlock support for Reactive Forms, Template-driven Forms, validation, form resets, disabling, and all the other powerful features of Angular's forms ecosystem.

Mastering CVA is essential if you want to create reusable UI libraries, design systems, or enterprise-grade Angular applications where custom form controls are a common requirement. Once you understand the data flow between Angular Forms and your component, implementing new form controls becomes a predictable and repeatable process.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Mastering Angular ControlValueAccessor (CVA): The Complete Guide with Real-World Examples

Thematisch verwandte Begriffe: Mastering, Angular, ControlValueAccessor, Complete · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-94109 | openEQUELLA versions before 2026.1.0 contain a remote code execution vul…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick