Which $destroy event should a directive with scope: false listen on for reliable listener cleanup?
0 reputation · 19 Oct 2022, 19:28 UTC
Context
A directive using scope: false shares its parent scope and registers listeners via scope.$on(event, handler). The AngularJS documentation states that the $destroy event fires on the scope being destroyed, but the timing and target scope differ between AngularJS 1.2–1.4 and 1.5+.
Goal
Determine the correct scope on which to register the $destroy cleanup handler so that the deregistration function returned by scope.$on() is called exactly once when the directive's element is removed, without leaking the parent scope or missing the event in any supported version.
Constraints
- The directive cannot request an isolate or child scope (
scope: falseis required). - The codebase must support AngularJS 1.4 through 1.8.
- No component controller or
$onDestroyhook is available because the directive uses a link function only.
Questions
- Should the cleanup handler be registered on the shared parent scope (
scope.$on('$destroy', cleanup)) or on the directive's own scope reference? - Does the
$destroyevent fire on the parent scope before or after the directive's link function has a chance to run its cleanup in AngularJS 1.4 versus 1.6? - Is there a version-agnostic pattern that guarantees the deregistration function executes without retaining a reference to the destroyed scope?