Skip to content

Commit 532e536

Browse files
committed
refactor(router): get guards only one time and simplify guard operator signature (angular#26239)
PR Close angular#26239
1 parent f859d83 commit 532e536

File tree

4 files changed

+58
-57
lines changed

4 files changed

+58
-57
lines changed

packages/router/src/operators/check_guards.ts

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,27 @@ import {concatMap, every, first, map, mergeMap} from 'rxjs/operators';
1212

1313
import {ActivationStart, ChildActivationStart, Event} from '../events';
1414
import {NavigationTransition} from '../router';
15-
import {ChildrenOutletContexts} from '../router_outlet_context';
1615
import {ActivatedRouteSnapshot, RouterStateSnapshot} from '../router_state';
1716
import {andObservables, wrapIntoObservable} from '../utils/collection';
18-
import {CanActivate, CanDeactivate, Checks, getAllRouteGuards, getCanActivateChild, getToken} from '../utils/preactivation';
17+
import {CanActivate, CanDeactivate, getCanActivateChild, getToken} from '../utils/preactivation';
1918

20-
export function checkGuards(
21-
rootContexts: ChildrenOutletContexts, moduleInjector: Injector,
22-
forwardEvent?: (evt: Event) => void): MonoTypeOperatorFunction<NavigationTransition> {
19+
export function checkGuards(moduleInjector: Injector, forwardEvent?: (evt: Event) => void):
20+
MonoTypeOperatorFunction<NavigationTransition> {
2321
return function(source: Observable<NavigationTransition>) {
2422

2523
return source.pipe(mergeMap(t => {
26-
const {targetSnapshot, currentSnapshot} = t;
27-
const checks = getAllRouteGuards(targetSnapshot !, currentSnapshot, rootContexts);
28-
if (checks.canDeactivateChecks.length === 0 && checks.canActivateChecks.length === 0) {
24+
const {targetSnapshot, currentSnapshot, guards: {canActivateChecks, canDeactivateChecks}} = t;
25+
if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) {
2926
return of ({...t, guardsResult: true});
3027
}
3128

32-
return runCanDeactivateChecks(checks, targetSnapshot !, currentSnapshot, moduleInjector)
29+
return runCanDeactivateChecks(
30+
canDeactivateChecks, targetSnapshot !, currentSnapshot, moduleInjector)
3331
.pipe(
3432
mergeMap((canDeactivate: boolean) => {
3533
return canDeactivate ?
36-
runCanActivateChecks(targetSnapshot !, checks, moduleInjector, forwardEvent) :
34+
runCanActivateChecks(
35+
targetSnapshot !, canActivateChecks, moduleInjector, forwardEvent) :
3736
of (false);
3837
}),
3938
map(guardsResult => ({...t, guardsResult})));
@@ -42,28 +41,26 @@ export function checkGuards(
4241
}
4342

4443
function runCanDeactivateChecks(
45-
checks: Checks, futureRSS: RouterStateSnapshot, currRSS: RouterStateSnapshot,
44+
checks: CanDeactivate[], futureRSS: RouterStateSnapshot, currRSS: RouterStateSnapshot,
4645
moduleInjector: Injector): Observable<boolean> {
47-
return from(checks.canDeactivateChecks)
48-
.pipe(
49-
mergeMap(
50-
(check: CanDeactivate) => runCanDeactivate(
51-
check.component, check.route, currRSS, futureRSS, moduleInjector)),
52-
every((result: boolean) => result === true));
46+
return from(checks).pipe(
47+
mergeMap(
48+
(check: CanDeactivate) =>
49+
runCanDeactivate(check.component, check.route, currRSS, futureRSS, moduleInjector)),
50+
every((result: boolean) => result === true));
5351
}
5452

5553
function runCanActivateChecks(
56-
futureSnapshot: RouterStateSnapshot, checks: Checks, moduleInjector: Injector,
54+
futureSnapshot: RouterStateSnapshot, checks: CanActivate[], moduleInjector: Injector,
5755
forwardEvent?: (evt: Event) => void): Observable<boolean> {
58-
return from(checks.canActivateChecks)
59-
.pipe(
60-
concatMap((check: CanActivate) => andObservables(from([
61-
fireChildActivationStart(check.route.parent, forwardEvent),
62-
fireActivationStart(check.route, forwardEvent),
63-
runCanActivateChild(futureSnapshot, check.path, moduleInjector),
64-
runCanActivate(futureSnapshot, check.route, moduleInjector)
65-
]))),
66-
every((result: boolean) => result === true));
56+
return from(checks).pipe(
57+
concatMap((check: CanActivate) => andObservables(from([
58+
fireChildActivationStart(check.route.parent, forwardEvent),
59+
fireActivationStart(check.route, forwardEvent),
60+
runCanActivateChild(futureSnapshot, check.path, moduleInjector),
61+
runCanActivate(futureSnapshot, check.route, moduleInjector)
62+
]))),
63+
every((result: boolean) => result === true));
6764
}
6865

6966
/**

packages/router/src/operators/resolve_data.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,23 @@ import {concatMap, last, map, mergeMap, reduce} from 'rxjs/operators';
1212

1313
import {ResolveData} from '../config';
1414
import {NavigationTransition} from '../router';
15-
import {ChildrenOutletContexts} from '../router_outlet_context';
1615
import {ActivatedRouteSnapshot, RouterStateSnapshot, inheritedParamsDataResolve} from '../router_state';
1716
import {wrapIntoObservable} from '../utils/collection';
1817

19-
import {getAllRouteGuards, getToken} from '../utils/preactivation';
18+
import {getToken} from '../utils/preactivation';
2019

2120
export function resolveData(
22-
rootContexts: ChildrenOutletContexts, paramsInheritanceStrategy: 'emptyOnly' | 'always',
21+
paramsInheritanceStrategy: 'emptyOnly' | 'always',
2322
moduleInjector: Injector): MonoTypeOperatorFunction<NavigationTransition> {
2423
return function(source: Observable<NavigationTransition>) {
2524
return source.pipe(mergeMap(t => {
26-
const {targetSnapshot, currentSnapshot} = t;
27-
const checks = getAllRouteGuards(targetSnapshot !, currentSnapshot, rootContexts);
25+
const {targetSnapshot, guards: {canActivateChecks}} = t;
2826

29-
if (!checks.canActivateChecks.length) {
27+
if (!canActivateChecks.length) {
3028
return of (t);
3129
}
3230

33-
return from(checks.canActivateChecks)
31+
return from(canActivateChecks)
3432
.pipe(
3533
concatMap(
3634
check => runResolve(

packages/router/src/router.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {ActivatedRoute, RouterState, RouterStateSnapshot, createEmptyState} from
2828
import {Params, isNavigationCancelingError} from './shared';
2929
import {DefaultUrlHandlingStrategy, UrlHandlingStrategy} from './url_handling_strategy';
3030
import {UrlSerializer, UrlTree, containsTree, createEmptyUrlTree} from './url_tree';
31-
import {getAllRouteGuards} from './utils/preactivation';
31+
import {Checks, getAllRouteGuards} from './utils/preactivation';
3232

3333

3434

@@ -185,6 +185,7 @@ export type NavigationTransition = {
185185
targetSnapshot: RouterStateSnapshot | null,
186186
currentRouterState: RouterState,
187187
targetRouterState: RouterState | null,
188+
guards: Checks,
188189
guardsResult: boolean | null,
189190
};
190191

@@ -354,6 +355,7 @@ export class Router {
354355
targetSnapshot: null,
355356
currentRouterState: this.routerState,
356357
targetRouterState: null,
358+
guards: {canActivateChecks: [], canDeactivateChecks: []},
357359
guardsResult: null,
358360
});
359361
this.navigations = this.setupNavigations(this.transitions);
@@ -478,9 +480,13 @@ export class Router {
478480
this.triggerEvent(guardsStart);
479481
}),
480482

481-
checkGuards(
482-
this.rootContexts, this.ngModule.injector,
483-
(evt: Event) => this.triggerEvent(evt)),
483+
map(t => ({
484+
...t,
485+
guards:
486+
getAllRouteGuards(t.targetSnapshot !, t.currentSnapshot, this.rootContexts)
487+
})),
488+
489+
checkGuards(this.ngModule.injector, (evt: Event) => this.triggerEvent(evt)),
484490

485491
tap(t => {
486492
const guardsEnd = new GuardsCheckEnd(
@@ -503,8 +509,7 @@ export class Router {
503509

504510
// --- RESOLVE ---
505511
switchTap(t => {
506-
if (getAllRouteGuards(t.targetSnapshot !, t.currentSnapshot, this.rootContexts)
507-
.canActivateChecks.length) {
512+
if (t.guards.canActivateChecks.length) {
508513
return of (t).pipe(
509514
tap(t => {
510515
const resolveStart = new ResolveStart(
@@ -513,7 +518,7 @@ export class Router {
513518
this.triggerEvent(resolveStart);
514519
}),
515520
resolveData(
516-
this.rootContexts, this.paramsInheritanceStrategy,
521+
this.paramsInheritanceStrategy,
517522
this.ngModule.injector), //
518523
tap(t => {
519524
const resolveEnd = new ResolveEnd(

packages/router/test/router.spec.ts

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {NavigationTransition, Router} from '../src/router';
1818
import {ChildrenOutletContexts} from '../src/router_outlet_context';
1919
import {RouterStateSnapshot, createEmptyStateSnapshot} from '../src/router_state';
2020
import {DefaultUrlSerializer} from '../src/url_tree';
21+
import {getAllRouteGuards} from '../src/utils/preactivation';
2122
import {TreeNode} from '../src/utils/tree';
2223
import {RouterTestingModule} from '../testing/src/router_testing_module';
2324

@@ -143,9 +144,8 @@ describe('Router', () => {
143144
const futureState = new (RouterStateSnapshot as any)(
144145
'url', new TreeNode(empty.root, [new TreeNode(childSnapshot, [])]));
145146

146-
of ({targetSnapshot: futureState, currentSnapshot: empty})
147-
.pipe(checkGuardsOperator(
148-
new ChildrenOutletContexts(), TestBed, (evt) => { events.push(evt); }))
147+
of ({guards: getAllRouteGuards(futureState, empty, new ChildrenOutletContexts())})
148+
.pipe(checkGuardsOperator(TestBed, (evt) => { events.push(evt); }))
149149
.subscribe((x) => result = !!x.guardsResult, (e) => { throw e; });
150150

151151
expect(result).toBe(true);
@@ -178,9 +178,8 @@ describe('Router', () => {
178178
new TreeNode(grandchildSnapshot, [new TreeNode(greatGrandchildSnapshot, [])])
179179
])]));
180180

181-
of ({targetSnapshot: futureState, currentSnapshot: empty})
182-
.pipe(checkGuardsOperator(
183-
new ChildrenOutletContexts(), TestBed, (evt) => { events.push(evt); }))
181+
of ({guards: getAllRouteGuards(futureState, empty, new ChildrenOutletContexts())})
182+
.pipe(checkGuardsOperator(TestBed, (evt) => { events.push(evt); }))
184183
.subscribe((x) => result = !!x.guardsResult, (e) => { throw e; });
185184

186185
expect(result).toBe(true);
@@ -211,9 +210,8 @@ describe('Router', () => {
211210
new TreeNode(
212211
empty.root, [new TreeNode(childSnapshot, [new TreeNode(grandchildSnapshot, [])])]));
213212

214-
of ({targetSnapshot: futureState, currentSnapshot: currentState})
215-
.pipe(checkGuardsOperator(
216-
new ChildrenOutletContexts(), TestBed, (evt) => { events.push(evt); }))
213+
of ({guards: getAllRouteGuards(futureState, currentState, new ChildrenOutletContexts())})
214+
.pipe(checkGuardsOperator(TestBed, (evt) => { events.push(evt); }))
217215
.subscribe((x) => result = !!x.guardsResult, (e) => { throw e; });
218216

219217
expect(result).toBe(true);
@@ -257,9 +255,8 @@ describe('Router', () => {
257255
greatGrandchildSnapshot, [new TreeNode(greatGreatGrandchildSnapshot, [])])
258256
])])]));
259257

260-
of ({targetSnapshot: futureState, currentSnapshot: currentState})
261-
.pipe(checkGuardsOperator(
262-
new ChildrenOutletContexts(), TestBed, (evt) => { events.push(evt); }))
258+
of ({guards: getAllRouteGuards(futureState, currentState, new ChildrenOutletContexts())})
259+
.pipe(checkGuardsOperator(TestBed, (evt) => { events.push(evt); }))
263260
.subscribe((x) => result = !!x.guardsResult, (e) => { throw e; });
264261

265262
expect(result).toBe(true);
@@ -538,15 +535,19 @@ describe('Router', () => {
538535

539536
function checkResolveData(
540537
future: RouterStateSnapshot, curr: RouterStateSnapshot, injector: any, check: any): void {
541-
of ({ targetSnapshot: future, currentSnapshot: curr } as Partial<NavigationTransition>)
542-
.pipe(resolveDataOperator(new ChildrenOutletContexts(), 'emptyOnly', injector))
538+
of ({
539+
guards: getAllRouteGuards(future, curr, new ChildrenOutletContexts())
540+
} as Partial<NavigationTransition>)
541+
.pipe(resolveDataOperator('emptyOnly', injector))
543542
.subscribe(check, (e) => { throw e; });
544543
}
545544

546545
function checkGuards(
547546
future: RouterStateSnapshot, curr: RouterStateSnapshot, injector: any,
548547
check: (result: boolean) => void): void {
549-
of ({ targetSnapshot: future, currentSnapshot: curr } as Partial<NavigationTransition>)
550-
.pipe(checkGuardsOperator(new ChildrenOutletContexts(), injector))
548+
of ({
549+
guards: getAllRouteGuards(future, curr, new ChildrenOutletContexts())
550+
} as Partial<NavigationTransition>)
551+
.pipe(checkGuardsOperator(injector))
551552
.subscribe(t => check(!!t.guardsResult), (e) => { throw e; });
552553
}

0 commit comments

Comments
 (0)