-
Notifications
You must be signed in to change notification settings - Fork 15
Description
Currently, the AngularDart router’s CanReuse hook works as expected when you implement it on a component whose route is being reactivated. However, if that component is rendered inside a parent route (i.e. as a sub-route), its own CanReuse implementation won’t be consulted unless the parent also implements CanReuse and returns true. This subtle requirement is not mentioned in the public docs, leading to confusion when developers find that their sub-route’s canReuse() is never called.
What’s Missing
The Routing Guide does not explain that:
- A sub-route’s CanReuse.canReuse(oldState, newState) will only be invoked if its parent component’s -
- CanReuse.canReuse(...) also returns true.
Therefore, to enable reuse logic for a child outlet, the parent component must itself implement CanReuse and allow reuse for the relevant state transitions.
Reproduction Steps
- Create a parent component (
ParentComponent) with a<router-outlet>for child routes. - Create a child component (
ChildComponent) that implementsCanReuseand logs or returnsfalsein itscanReuse()method. - Navigate from one sibling route to another (e.g.
/parent/childA→/parent/childB). - Observe that
ChildComponent.canReuse()is not called, even thoughChildComponentimplementsCanReuse.
Expected Behavior
When navigating between child routes under the same parent, the child’s CanReuse.canReuse() should always be invoked to decide reuse or destruction of the component instance—regardless of whether the parent implements CanReuse.
Actual Behavior
AngularDart currently skips the child’s canReuse() call if the parent does not implement CanReuse or returns false. This is by design (due to hierarchical activation logic), but it isn’t documented anywhere in the official guide.
Proposed Documentation Update
Under the Route Lifecycle or CanReuse section in the Routing Guide:
-
Explain the hierarchical reuse check:
“Note: The router traverses outlets from the root down. It will only call a component’s
canReuse()if all of its ancestor outlets also agree to reuse. That means any parent component hosting a<router-outlet>for this route must itself implementCanReuse(and returntrue) in order for the child’scanReuse()to be evaluated.” -
Add a small code example:
@Component(
selector: 'parent-comp',
template: '<router-outlet></router-outlet>',
)
class ParentComponent implements CanReuse {
@override
Future<bool> canReuse(RouterState oldState, RouterState newState) async {
// allow reuse whenever the parent’s path params haven’t changed
return oldState.parameters['id'] == newState.parameters['id'];
}
}
@Component(
selector: 'child-comp',
template: '<p>Child content</p>',
)
class ChildComponent implements CanReuse {
@override
Future<bool> canReuse(RouterState oldState, RouterState newState) async {
// decide reuse based on child-specific logic
return true;
}
}Thank you for considering this enhancement—adding these details will help developers avoid unexpected behavior and fully leverage the CanReuse lifecycle hook in nested routing scenarios.