fix(router): adjust ChildActivation events to only fire when the child is actually changing (#19043)
* The problem was with the `fireChildActivationStart` function. It was taking a `path` param, which was an array of `ActivatedRouteSnapshot`s. The function was being fired for each piece of the route that was being activated. This resulted in far too many `ChildActivationStart` events being fired, and being fired on routes that weren't actually getting activated. This change fires the event only for those routes that are actually being activated. fixes #18942 PR Close #19043
This commit is contained in:
@ -7,7 +7,8 @@
|
||||
*/
|
||||
|
||||
import {Route} from './config';
|
||||
import {RouterStateSnapshot} from './router_state';
|
||||
import {ActivatedRouteSnapshot, RouterStateSnapshot} from './router_state';
|
||||
|
||||
|
||||
/**
|
||||
* @whatItDoes Base for events the Router goes through, as opposed to events tied to a specific
|
||||
@ -264,8 +265,11 @@ export class RouteConfigLoadEnd {
|
||||
export class ChildActivationStart {
|
||||
constructor(
|
||||
/** @docsNotRequired */
|
||||
public route: Route) {}
|
||||
toString(): string { return `ChildActivationStart(path: '${this.route.path}')`; }
|
||||
public snapshot: ActivatedRouteSnapshot) {}
|
||||
toString(): string {
|
||||
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
|
||||
return `ChildActivationStart(path: '${path}')`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -277,8 +281,11 @@ export class ChildActivationStart {
|
||||
export class ChildActivationEnd {
|
||||
constructor(
|
||||
/** @docsNotRequired */
|
||||
public route: Route) {}
|
||||
toString(): string { return `ChildActivationEnd(path: '${this.route.path}')`; }
|
||||
public snapshot: ActivatedRouteSnapshot) {}
|
||||
toString(): string {
|
||||
const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
|
||||
return `ChildActivationEnd(path: '${path}')`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -202,8 +202,8 @@ export class PreActivation {
|
||||
const checks$ = from(this.canActivateChecks);
|
||||
const runningChecks$ = concatMap.call(
|
||||
checks$, (check: CanActivate) => andObservables(from([
|
||||
this.fireChildActivationStart(check.path), this.runCanActivateChild(check.path),
|
||||
this.runCanActivate(check.route)
|
||||
this.fireChildActivationStart(check.route.parent),
|
||||
this.runCanActivateChild(check.path), this.runCanActivate(check.route)
|
||||
])));
|
||||
return every.call(runningChecks$, (result: boolean) => result === true);
|
||||
// this.fireChildActivationStart(check.path),
|
||||
@ -217,16 +217,11 @@ export class PreActivation {
|
||||
* return
|
||||
* `true` so checks continue to run.
|
||||
*/
|
||||
private fireChildActivationStart(path: ActivatedRouteSnapshot[]): Observable<boolean> {
|
||||
if (!this.forwardEvent) return of (true);
|
||||
const childActivations = path.slice(0, path.length - 1).reverse().filter(_ => _ !== null);
|
||||
|
||||
return andObservables(map.call(from(childActivations), (snapshot: ActivatedRouteSnapshot) => {
|
||||
if (this.forwardEvent && snapshot._routeConfig) {
|
||||
this.forwardEvent(new ChildActivationStart(snapshot._routeConfig));
|
||||
}
|
||||
return of (true);
|
||||
}));
|
||||
private fireChildActivationStart(snapshot: ActivatedRouteSnapshot|null): Observable<boolean> {
|
||||
if (snapshot !== null && this.forwardEvent) {
|
||||
this.forwardEvent(new ChildActivationStart(snapshot));
|
||||
}
|
||||
return of (true);
|
||||
}
|
||||
private runCanActivate(future: ActivatedRouteSnapshot): Observable<boolean> {
|
||||
const canActivate = future._routeConfig ? future._routeConfig.canActivate : null;
|
||||
|
@ -21,7 +21,7 @@ import {applyRedirects} from './apply_redirects';
|
||||
import {LoadedRouterConfig, QueryParamsHandling, Route, Routes, validateConfig} from './config';
|
||||
import {createRouterState} from './create_router_state';
|
||||
import {createUrlTree} from './create_url_tree';
|
||||
import {ChildActivationEnd, Event, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouterEvent, RoutesRecognized} from './events';
|
||||
import {ChildActivationEnd, Event, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RoutesRecognized} from './events';
|
||||
import {PreActivation} from './pre_activation';
|
||||
import {recognize} from './recognize';
|
||||
import {DefaultRouteReuseStrategy, DetachedRouteHandleInternal, RouteReuseStrategy} from './route_reuse_strategy';
|
||||
@ -864,8 +864,8 @@ class ActivateRoutes {
|
||||
const children: {[outlet: string]: any} = nodeChildrenAsMap(currNode);
|
||||
futureNode.children.forEach(
|
||||
c => { this.activateRoutes(c, children[c.value.outlet], contexts); });
|
||||
if (futureNode.children.length && futureNode.value.routeConfig) {
|
||||
this.forwardEvent(new ChildActivationEnd(futureNode.value.routeConfig));
|
||||
if (futureNode.children.length) {
|
||||
this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user