fix(router): shouldn't execute CanLoad when a route has been loaded

Closes #14475
Closes #15438
This commit is contained in:
Dzmitry Shylovich 2017-03-24 01:59:17 +03:00 committed by Victor Berchet
parent fb1be83a1b
commit 8785b2bf6d
2 changed files with 55 additions and 8 deletions

View File

@ -293,16 +293,18 @@ class ApplyRedirects {
}
if (route.loadChildren) {
if ((<any>route)._loadedConfig !== void 0) {
return of ((<any>route)._loadedConfig);
}
return mergeMap.call(runCanLoadGuard(ngModule.injector, route), (shouldLoad: boolean) => {
if (shouldLoad) {
return (<any>route)._loadedConfig ?
of ((<any>route)._loadedConfig) :
map.call(
this.configLoader.load(ngModule.injector, route), (cfg: LoadedRouterConfig) => {
(<any>route)._loadedConfig = cfg;
return cfg;
});
return map.call(
this.configLoader.load(ngModule.injector, route), (cfg: LoadedRouterConfig) => {
(<any>route)._loadedConfig = cfg;
return cfg;
});
}
return canLoadFails(route);

View File

@ -2075,7 +2075,9 @@ describe('Integration', () => {
});
describe('CanLoad', () => {
let canLoadRunCount = 0;
beforeEach(() => {
canLoadRunCount = 0;
TestBed.configureTestingModule({
providers: [
{provide: 'alwaysFalse', useValue: (a: any) => false},
@ -2087,7 +2089,13 @@ describe('Integration', () => {
},
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']
]);
})));
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', () => {