FORM_NODE
FORM_NODE is the Angular injection token for the concrete [formNode] binding on the current
host. Use it when a colocated directive or service needs that exact rendered control.
📐 Type
const FORM_NODE: InjectionToken<FormNodeBinding<AnyNode>>;
🔌 Same-host injection
import { FORM_NODE } from '@ngblocks/form-nodes';
import { Directive, inject } from '@angular/core';
@Directive({
selector: '[focusInvalidNode]',
host: { '(click)': 'focusWhenInvalid()' },
})
export class FocusInvalidNode {
private binding = inject(FORM_NODE, { self: true });
focusWhenInvalid() {
if (this.binding.node().invalid()) this.binding.focus();
}
}
Use { self: true } to avoid resolving an ancestor control. If the directive also supports hosts
without [formNode], add optional: true; injection then returns null when absent.
🔌 Binding surface
| Member | Purpose |
|---|---|
node() | Current bound node |
errors() | Errors visible to this binding |
element | Host HTMLElement |
injector | Host injector |
focus(options?) | Focuses this exact control |
flush() | Commits a pending control value |
reset() | Resets interaction and parsing state |
Rebinding updates node() reactively. FORM_NODE represents a concrete binding, not merely a
model node; use the node API when code does not care which rendered control is involved.
Most components can use #binding="formNode" with viewChild() instead of injection.
See [formNode] and Node API.
Custom components can inject this token during construction without changing output ordering.
With immediate updates, valueChange, checkedChange, and touch template handlers see the
updated node value or touched state. Configured debounce still applies. The token continues to
resolve to the concrete directive instance.
See custom output ordering.
For a reactive owning-form lookup, use useClosestFormState(). It wraps optional injection and model ownership resolution, and exposes the form's submission history through its result.