In this exercise we will learn how to use the ChangeDetectorRef
to manually
inform angular about changes when needed.
[!NOTICE] REMEMBER the bug where you have to just click or hover something in the app until your changes are displayed on the screen? We are here to solve it now :).
This time, we are not missing out an NgZone tick, but we need to inform the framework about a change that needs to get detected.
Go to the movie-list-page.component.ts
:
- inject
ChangeDetectorRef
- use
markForCheck
after setting themovies
value.
cdRef#markForCheck: MovieListPageComponent
// movie-list-page.component.ts
import { ChangeDetectorRef } from '@angular/core';
private cdRef = inject(ChangeDetectorRef); // 👈️👈️👈️👈️
constructor() {
this.activatedRoute.params.subscribe((params) => {
if (params.category) {
this.paginate((page) =>
this.movieService.getMovieList(params.category, page),
).subscribe((movies) => {
this.movies = movies;
this.cdRef.markForCheck(); // 👈️👈️👈️👈️
});
} else {
this.paginate((page) =>
this.movieService.getMoviesByGenre(params.id, page),
).subscribe((movies) => {
this.movies = movies;
this.cdRef.markForCheck(); // 👈️👈️👈️👈️
});
}
});
}
Also the tilt effect doesn't work again.
Go to the tilt.directive.component.ts
:
- inject
ChangeDetectorRef
- use
markForCheck
after setting therotate
markForCheck: TiltDirective
// tilt.directive.ts
export class TiltDirective {
private cdRef = inject(ChangeDetectorRef); // 👈️👈️👈️👈️
constructor(private elementRef: ElementRef<HTMLElement>) {
const rotate$ = fromEvent<MouseEvent>(
this.elementRef.nativeElement,
'mouseenter',
).pipe(map((event) => this.getRotationDegree(event)));
const reset$ = fromEvent(this.elementRef.nativeElement, 'mouseleave').pipe(
map(() => this.getDefaultRotation()),
);
merge(rotate$, reset$).subscribe((rotate) => {
this.rotate = rotate;
this.cdRef.markForCheck(); // 👈️👈️👈️👈️
});
}
}