Not that anybody need care about my opinion, but for what it’s worth, I think lifecycle events should not be (ab)used to solve the general problem of “displaying stale data”. What people tend to do:
interface Profile {
name: string;
// ...
}
class ProfileService {
profile: Profile;
}
class ProfileDisplayPage {
profile: Profile;
constructor(private profiler: ProfileService) {}
ngOnInit(): void { this.profile = this.profiler.profile; }
}
class ProfileEditPage {
profile: Profile;
constructor(private profiler: ProfileService) {}
updateProfile(): void { this.profiler.profile = this.profile; }
}
…then they ask “how do I force reloading of ProfileDisplayPage
?”
What I do is to leverage RxJS to solve the problem of “how do I ensure that updates propagate easily and efficiently across my app?”:
class ProfileService {
profile$ = new BehaviorSubject<Profile | null>(null);
watchProfile(): Observable<Profile | null> { return this.profile$; }
peekProfile(): Profile | null { return this.profile$.value; }
pokeProfile(profile: Profile): void { this.profile$.next(profile); }
}
class ProfileDisplayPage {
profile$: Observable<Profile | null>;
constructor(private profiler: ProfileService) { this.profile$ = profiler.watchProfile(); }
}
class ProfileEditPage {
profile: Profile;
constructor(private profiler: ProfileService) { this.profile = profiler.peekProfile(); }
updateProfile(): void { this.profiler.pokeProfile(this.profile); }
}
There are a myriad of options for accessing Observable
s from a template. Many of them involve memory leaks or overly verbose boilerplate. Two that don’t are the AsyncPipe and NetanelBasal’s ngx-take-until-destroy.
I frequently think in terms of “WORM (Write Once / Read Multiple) brokers”, where a resource has many readers and a single writer. The broker in this case is the ProfileService
, which is injected by anybody interested in the Profile
resource. It exposes three operations: watch
, peek
, and poke
. Readers who want updates want watch
. Transient readers that don’t care about updates can use peek
. Writers generally take a snapshot with peek
, modify it, and push the updates back with poke
.
All of this happens with no additional code on the part of readers, no dependencies on the vagaries of framework internals (such as what lifecycle events fire when on what UI components), and no wasteful performance hits (such as you see with “solutions” to this problem that completely rerender a bunch of irrelevant stuff, often via action-at-a-distance).
It is also easy (and transparent) to add network and/or backing on-device storage to ProfileService
. Nobody outside that class has to know or care when or how external forces collude to bring fresh data.