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
