`ngOnChanges` is an Angular lifecycle hook for responding to input-property changes in a directive or component. Angular calls it once before `ngOnInit`, then again when an input changes. Updating an input does not, by itself, make a directive revise work it has already done: a class previously added to an element, for example, stays there until the directive removes it. section 14.3.3
When change details matter, accept a `SimpleChanges` parameter and look up the changed input by its property name. Its `SimpleChange` supplies `previousValue`, `currentValue`, and `isFirstChange()`. Check the first-change flag before undoing an earlier effect: on the initial call, the previous value may never have been applied. section 14.3.3
Table 14.4. The properties and method of the SimpleChange class
|
Name
|
Description
|
|
previousValue
|
This property returns the previous value of the input property.
|
|
currentValue
|
This property returns the current value of the input property.
|
|
isFirstChange()
|
This method returns
true if this is the call to the
ngOnChanges method that occurs before the
ngOnInit method.
|
Use these `SimpleChange` members to distinguish an initial assignment from a later change and to replace an effect tied to the old value. section 14.3.3
Keep an attribute directive’s classes current
A table-cell directive receives a CSS class through `bgClass`. When adding a product changes the binding expression, Angular updates that input on existing directive instances. In `ngOnChanges(changes: SimpleChanges)`, read `changes["bgClass"]`; remove `previousValue` from the element’s class list only if this is not the first change and the class is present, then add `currentValue` if needed. New and existing elements can now reflect the same background-class decision. section 14.3.3
Show or remove a structural directive’s view
A conditional structural directive receives the result of a template expression as an input. Its `ngOnChanges` reads that input’s change: when the current value is true, it calls `ViewContainerRef.createEmbeddedView` with its `TemplateRef`; when a later value is false, it calls `clear()`. Here the notification changes which HTML view exists, rather than an element’s class. section 15.2.1
Listing 15.5. The contents of the structure.directive.ts file in the src/app folder
import {
Directive, SimpleChanges, ViewContainerRef, TemplateRef, Input
} from "@angular/core";
@Directive({
selector: "[paIf]"
})
export class PaStructureDirective {
constructor(private container: ViewContainerRef,
private template: TemplateRef<Object>) { }
@Input("paIf")
expressionResult: boolean | undefined;
ngOnChanges(changes: SimpleChanges) {
let change = changes["expressionResult"];
if (!change.isFirstChange() && !change.currentValue) {
this.container.clear();
} else if (change.currentValue) {
this.container.createEmbeddedView(this.template);
}
}
}
The directive listing puts the input, change lookup, first-change check, and view-container operations together. section 15.2.1
The same hook is useful in components whose inputs change without a new component instance. During navigation between URLs handled by one component, Angular can reuse it and update its route-derived inputs; selecting a product in `ngOnChanges` makes Previous and Next navigation update the form. For a child-route category, an ordinary input is not itself a signal: copying its changes into a signal lets a computed product count reflect the active category. section 25.3.1 section 25.4.2
Other input-driven work follows the same pattern. A two-way-binding directive uses `ngOnChanges` to copy a changed model value into an input element’s host-bound `value`; an input event and output property handle the reverse direction. A custom validation directive creates a new validator when its input value changes, then uses that validator when assessing a control. Use the hook for the response needed by the input change, not as a replacement for those separate event or validation mechanisms. section 14.6 section 22.3.1
