liveBook · Manning

Differ

As explained in Pro Angular 16

A differ is a change-comparison mechanism that detects additions, removals, or moves in a data structure.

A differ detects changes in a data structure, such as additions, removals, or moves, so application code can respond when ordinary binding updates are insufficient. section 18.2.3 section 25.1.1

Angular uses differs in practical change-response patterns:

  • Inject KeyValueDiffers into a directive, create a differ for a service object, and check it during ngDoCheck. section 18.2.3
  • Track changes to a service property without manually storing the previous update; alternatively, compare the current value with a saved previous value. section 18.2.3
  • Use a differ to monitor model changes and derive a count of unique product categories. section 25.1.1

Discount-aware directive

A price directive receives both a DiscountService and KeyValueDiffers. During initialization it creates a differ for the service, responds to input-price changes in ngOnChanges, and checks service changes in ngDoCheck before updating discountAmount.

Listing 18.18. The contents of the discountAmount.directive.ts file in the src/app folder
import { Directive, Input,SimpleChange, KeyValueDiffer, 
    KeyValueDiffers } from "@angular/core";
import { DiscountService } from "./discount.service";
 
@Directive({
    selector: "td[pa-price]",
    exportAs: "discount"
})
export class PaDiscountAmountDirective {
    private differ?: KeyValueDiffer<any, any>;
 
    constructor(private keyValueDiffers: KeyValueDiffers,
        private discount: DiscountService) { }
 
    @Input({ alias: "pa-price", required: true})
    originalPrice!: number;
 
    discountAmount?: number;
 
    ngOnInit() {
        this.differ =
            this.keyValueDiffers.find(this.discount).create();
    }
 
    ngOnChanges(changes: { [property: string]: SimpleChange }) {
        if (changes["originalPrice"] != null) {
            this.updateValue();
        }
    }
 
    ngDoCheck() {
        if (this.differ?.diff(this.discount) != null) {
            this.updateValue();
        }
    }
 
    private updateValue() {
        this.discountAmount 
            = this.discount.applyDiscount(this.originalPrice);
    }
}

Inspect the directive listing for the injected KeyValueDiffers dependency, differ field, initialization, and input-change handling. section 18.2.3

How Pro Angular 16 covers it

How deep it goes
Explains dependency injection, differ creation, lifecycle checks, and a manual previous-value alternative, but does not detail differ internals.
Examples
Demonstrates discounted product prices and tracking unique product categories in an Angular application.
What it assumes
Assumes Angular components or directives, injected services, inputs, and lifecycle hooks such as ngOnChanges and ngDoCheck.
What you can do after
Apply it via Angular's KeyValueDiffers service to react to service-object changes inside a directive lifecycle.
How it connects
Connects differs with Angular directives, components, services, dependency injection, data binding, and lifecycle hooks.

This explainer was generated by Manning's knowledge graph from the text of Pro Angular 16. The section links point to the parts of the book it draws on.