Setting the state to "childActivate" has no effect, because the component is being destroyed within the next change detection step, so state switches to void instead.
This is how i solved this issue:
I delay the route change by 1 further change detection cycle. I use a CanDeactivate Guard for this, which listens for a promise to resolve.
Check out my plnkr:
https://embed.plnkr.co/cOeDfXCetaYuXFaZ7WeO/
Within route definitions i add:
canDeactivate: [CanDeactivateAfterChangeDetectionGuard]
This is the CanDeactivate Guard:
@Injectable()
class CanDeactivateAfterChangeDetectionGuard implements CanDeactivate<WaitForChangeDetection> {
canDeactivate(component: WaitForChangeDetection): Promise<boolean> {
return component.waitForChangeDetection();
}
}
which works with any component implementing this interface:
declare abstract class WaitForChangeDetection {
abstract waitForChangeDetection(): Promise<boolean>;
}
I created a base component with a default implementation of this interface
@Component({})
class WaitForChangeDetectionImpl implements AfterViewChecked, WaitForChangeDetection {
constructor(private cdRef: ChangeDetectorRef){
this.viewChecked$ = new Subject<void>();
}
viewChecked$: Subject<void>;
waitForChangeDetection(): Promise<boolean>{
this.cdRef.detectChanges();
return new Promise((resolve) => this.viewChecked$.subscribe(() => resolve(true)));
}
ngAfterViewChecked(){
this.viewChecked$.next();
}
}
So you can extend this component to provide the functionality to work with the guard for any component.
@Component({})
class ComponentA extends WaitForChangeDetectionImpl {
...
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…