fix(router): shouldn't execute CanLoad when a route has been loaded
Closes #14475 Closes #15438
This commit is contained in:
parent
fb1be83a1b
commit
8785b2bf6d
|
@ -293,16 +293,18 @@ class ApplyRedirects {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (route.loadChildren) {
|
if (route.loadChildren) {
|
||||||
|
if ((<any>route)._loadedConfig !== void 0) {
|
||||||
|
return of ((<any>route)._loadedConfig);
|
||||||
|
}
|
||||||
|
|
||||||
return mergeMap.call(runCanLoadGuard(ngModule.injector, route), (shouldLoad: boolean) => {
|
return mergeMap.call(runCanLoadGuard(ngModule.injector, route), (shouldLoad: boolean) => {
|
||||||
|
|
||||||
if (shouldLoad) {
|
if (shouldLoad) {
|
||||||
return (<any>route)._loadedConfig ?
|
return map.call(
|
||||||
of ((<any>route)._loadedConfig) :
|
this.configLoader.load(ngModule.injector, route), (cfg: LoadedRouterConfig) => {
|
||||||
map.call(
|
(<any>route)._loadedConfig = cfg;
|
||||||
this.configLoader.load(ngModule.injector, route), (cfg: LoadedRouterConfig) => {
|
return cfg;
|
||||||
(<any>route)._loadedConfig = cfg;
|
});
|
||||||
return cfg;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return canLoadFails(route);
|
return canLoadFails(route);
|
||||||
|
|
|
@ -2075,7 +2075,9 @@ describe('Integration', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('CanLoad', () => {
|
describe('CanLoad', () => {
|
||||||
|
let canLoadRunCount = 0;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
canLoadRunCount = 0;
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [
|
providers: [
|
||||||
{provide: 'alwaysFalse', useValue: (a: any) => false},
|
{provide: 'alwaysFalse', useValue: (a: any) => false},
|
||||||
|
@ -2087,7 +2089,13 @@ describe('Integration', () => {
|
||||||
},
|
},
|
||||||
deps: [Router],
|
deps: [Router],
|
||||||
},
|
},
|
||||||
{provide: 'alwaysTrue', useValue: (a: any) => true},
|
{
|
||||||
|
provide: 'alwaysTrue',
|
||||||
|
useValue: () => {
|
||||||
|
canLoadRunCount++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2173,6 +2181,43 @@ describe('Integration', () => {
|
||||||
[NavigationStart, '/blank'], [RoutesRecognized, '/blank'], [NavigationEnd, '/blank']
|
[NavigationStart, '/blank'], [RoutesRecognized, '/blank'], [NavigationEnd, '/blank']
|
||||||
]);
|
]);
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
it('should execute CanLoad only once',
|
||||||
|
fakeAsync(inject(
|
||||||
|
[Router, Location, NgModuleFactoryLoader],
|
||||||
|
(router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => {
|
||||||
|
|
||||||
|
@Component({selector: 'lazy', template: 'lazy-loaded'})
|
||||||
|
class LazyLoadedComponent {
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [LazyLoadedComponent],
|
||||||
|
imports:
|
||||||
|
[RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])]
|
||||||
|
})
|
||||||
|
class LazyLoadedModule {
|
||||||
|
}
|
||||||
|
|
||||||
|
loader.stubbedModules = {lazy: LazyLoadedModule};
|
||||||
|
const fixture = createRoot(router, RootCmp);
|
||||||
|
|
||||||
|
router.resetConfig([{path: 'lazy', canLoad: ['alwaysTrue'], loadChildren: 'lazy'}]);
|
||||||
|
|
||||||
|
router.navigateByUrl('/lazy/loaded');
|
||||||
|
advance(fixture);
|
||||||
|
expect(location.path()).toEqual('/lazy/loaded');
|
||||||
|
expect(canLoadRunCount).toEqual(1);
|
||||||
|
|
||||||
|
router.navigateByUrl('/');
|
||||||
|
advance(fixture);
|
||||||
|
expect(location.path()).toEqual('/');
|
||||||
|
|
||||||
|
router.navigateByUrl('/lazy/loaded');
|
||||||
|
advance(fixture);
|
||||||
|
expect(location.path()).toEqual('/lazy/loaded');
|
||||||
|
expect(canLoadRunCount).toEqual(1);
|
||||||
|
})));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('order', () => {
|
describe('order', () => {
|
||||||
|
|
Loading…
Reference in New Issue