fix(router): should pass new data to Observable when query params change (#15387)
Fixes #15290
This commit is contained in:
parent
376088da70
commit
08f2f08d74
|
@ -381,7 +381,7 @@ export function advanceActivatedRoute(route: ActivatedRoute): void {
|
||||||
if (!shallowEqualArrays(currentSnapshot.url, route._futureSnapshot.url)) {
|
if (!shallowEqualArrays(currentSnapshot.url, route._futureSnapshot.url)) {
|
||||||
(<any>route.url).next(route._futureSnapshot.url);
|
(<any>route.url).next(route._futureSnapshot.url);
|
||||||
}
|
}
|
||||||
if (!equalParamsAndUrlSegments(currentSnapshot, route._futureSnapshot)) {
|
if (!shallowEqual(currentSnapshot.data, route._futureSnapshot.data)) {
|
||||||
(<any>route.data).next(route._futureSnapshot.data);
|
(<any>route.data).next(route._futureSnapshot.data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -400,4 +400,4 @@ export function equalParamsAndUrlSegments(
|
||||||
|
|
||||||
return equalUrlParams && !parentsMismatch &&
|
return equalUrlParams && !parentsMismatch &&
|
||||||
(!a.parent || equalParamsAndUrlSegments(a.parent, b.parent));
|
(!a.parent || equalParamsAndUrlSegments(a.parent, b.parent));
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||||
import {Observable} from 'rxjs/Observable';
|
import {Observable} from 'rxjs/Observable';
|
||||||
import {map} from 'rxjs/operator/map';
|
import {map} from 'rxjs/operator/map';
|
||||||
|
|
||||||
import {ActivatedRoute, ActivatedRouteSnapshot, CanActivate, CanDeactivate, DetachedRouteHandle, Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, PRIMARY_OUTLET, ParamMap, Params, PreloadAllModules, PreloadingStrategy, Resolve, RouteConfigLoadEnd, RouteConfigLoadStart, RouteReuseStrategy, Router, RouterModule, RouterStateSnapshot, RoutesRecognized, UrlHandlingStrategy, UrlSegmentGroup, UrlTree} from '../index';
|
import {ActivatedRoute, ActivatedRouteSnapshot, CanActivate, CanDeactivate, DetachedRouteHandle, Event, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, PRIMARY_OUTLET, ParamMap, Params, PreloadAllModules, PreloadingStrategy, Resolve, RouteConfigLoadEnd, RouteConfigLoadStart, RouteReuseStrategy, Router, RouterModule, RouterStateSnapshot, RoutesRecognized, RunGuardsAndResolvers, UrlHandlingStrategy, UrlSegmentGroup, UrlTree} from '../index';
|
||||||
import {RouterPreloader} from '../src/router_preloader';
|
import {RouterPreloader} from '../src/router_preloader';
|
||||||
import {forEach} from '../src/utils/collection';
|
import {forEach} from '../src/utils/collection';
|
||||||
import {RouterTestingModule, SpyNgModuleFactoryLoader} from '../testing';
|
import {RouterTestingModule, SpyNgModuleFactoryLoader} from '../testing';
|
||||||
|
@ -897,12 +897,8 @@ describe('Integration', () => {
|
||||||
router.navigateByUrl('/parent/2');
|
router.navigateByUrl('/parent/2');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
|
|
||||||
expect(primaryRecorded).toEqual([
|
expect(primaryRecorded).toEqual([{one: 1, three: 3, two: 2, four: 4}]);
|
||||||
{one: 1, three: 3, two: 2, four: 4}, {one: 1, three: 3, two: 2, four: 4}
|
expect(rightRecorded).toEqual([{one: 1, five: 5, two: 2, six: 6}]);
|
||||||
]);
|
|
||||||
expect(rightRecorded).toEqual([
|
|
||||||
{one: 1, five: 5, two: 2, six: 6}, {one: 1, five: 5, two: 2, six: 6}
|
|
||||||
]);
|
|
||||||
})));
|
})));
|
||||||
|
|
||||||
it('should handle errors', fakeAsync(inject([Router], (router: Router) => {
|
it('should handle errors', fakeAsync(inject([Router], (router: Router) => {
|
||||||
|
@ -1529,120 +1525,135 @@ describe('Integration', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('runGuardsAndResolvers', () => {
|
describe('runGuardsAndResolvers', () => {
|
||||||
let count = 0;
|
let guardRunCount = 0;
|
||||||
|
let resolverRunCount = 0;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
count = 0;
|
guardRunCount = 0;
|
||||||
|
resolverRunCount = 0;
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
providers: [{
|
providers: [
|
||||||
provide: 'loggingCanActivate',
|
{
|
||||||
useValue: (a: any, b: any) => {
|
provide: 'guard',
|
||||||
count++;
|
useValue: () => {
|
||||||
return true;
|
guardRunCount++;
|
||||||
}
|
return true;
|
||||||
}]
|
}
|
||||||
|
},
|
||||||
|
{provide: 'resolver', useValue: () => resolverRunCount++}
|
||||||
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should rerun guards when params change',
|
function configureRouter(router: Router, runGuardsAndResolvers: RunGuardsAndResolvers):
|
||||||
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
|
ComponentFixture<RootCmpWithTwoOutlets> {
|
||||||
const fixture = createRoot(router, RootCmpWithTwoOutlets);
|
const fixture = createRoot(router, RootCmpWithTwoOutlets);
|
||||||
|
|
||||||
router.resetConfig([
|
router.resetConfig([
|
||||||
{
|
{
|
||||||
path: 'a',
|
path: 'a',
|
||||||
runGuardsAndResolvers: 'paramsChange',
|
runGuardsAndResolvers,
|
||||||
component: SimpleCmp,
|
component: RouteCmp,
|
||||||
canActivate: ['loggingCanActivate']
|
canActivate: ['guard'],
|
||||||
},
|
resolve: {data: 'resolver'}
|
||||||
{path: 'b', component: SimpleCmp, outlet: 'right'}
|
},
|
||||||
]);
|
{path: 'b', component: SimpleCmp, outlet: 'right'}
|
||||||
|
]);
|
||||||
|
|
||||||
router.navigateByUrl('/a');
|
router.navigateByUrl('/a');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(count).toEqual(1);
|
return fixture;
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should rerun guards and resolvers when params change',
|
||||||
|
fakeAsync(inject([Router], (router: Router) => {
|
||||||
|
const fixture = configureRouter(router, 'paramsChange');
|
||||||
|
|
||||||
|
const cmp: RouteCmp = fixture.debugElement.children[1].componentInstance;
|
||||||
|
const recordedData: any[] = [];
|
||||||
|
cmp.route.data.subscribe((data: any) => recordedData.push(data));
|
||||||
|
|
||||||
|
expect(guardRunCount).toEqual(1);
|
||||||
|
expect(recordedData).toEqual([{data: 0}]);
|
||||||
|
|
||||||
router.navigateByUrl('/a;p=1');
|
router.navigateByUrl('/a;p=1');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(count).toEqual(2);
|
expect(guardRunCount).toEqual(2);
|
||||||
|
expect(recordedData).toEqual([{data: 0}, {data: 1}]);
|
||||||
|
|
||||||
router.navigateByUrl('/a;p=2');
|
router.navigateByUrl('/a;p=2');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(count).toEqual(3);
|
expect(guardRunCount).toEqual(3);
|
||||||
|
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]);
|
||||||
|
|
||||||
router.navigateByUrl('/a;p=2?q=1');
|
router.navigateByUrl('/a;p=2?q=1');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(count).toEqual(3);
|
expect(guardRunCount).toEqual(3);
|
||||||
|
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]);
|
||||||
})));
|
})));
|
||||||
|
|
||||||
it('should rerun guards when query params change',
|
it('should rerun guards and resolvers when query params change',
|
||||||
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
|
fakeAsync(inject([Router], (router: Router) => {
|
||||||
const fixture = createRoot(router, RootCmpWithTwoOutlets);
|
const fixture = configureRouter(router, 'paramsOrQueryParamsChange');
|
||||||
|
|
||||||
router.resetConfig([
|
const cmp: RouteCmp = fixture.debugElement.children[1].componentInstance;
|
||||||
{
|
const recordedData: any[] = [];
|
||||||
path: 'a',
|
cmp.route.data.subscribe((data: any) => recordedData.push(data));
|
||||||
runGuardsAndResolvers: 'paramsOrQueryParamsChange',
|
|
||||||
component: SimpleCmp,
|
|
||||||
canActivate: ['loggingCanActivate']
|
|
||||||
},
|
|
||||||
{path: 'b', component: SimpleCmp, outlet: 'right'}
|
|
||||||
]);
|
|
||||||
|
|
||||||
router.navigateByUrl('/a');
|
expect(guardRunCount).toEqual(1);
|
||||||
advance(fixture);
|
expect(recordedData).toEqual([{data: 0}]);
|
||||||
expect(count).toEqual(1);
|
|
||||||
|
|
||||||
router.navigateByUrl('/a;p=1');
|
router.navigateByUrl('/a;p=1');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(count).toEqual(2);
|
expect(guardRunCount).toEqual(2);
|
||||||
|
expect(recordedData).toEqual([{data: 0}, {data: 1}]);
|
||||||
|
|
||||||
router.navigateByUrl('/a;p=2');
|
router.navigateByUrl('/a;p=2');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(count).toEqual(3);
|
expect(guardRunCount).toEqual(3);
|
||||||
|
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]);
|
||||||
|
|
||||||
router.navigateByUrl('/a;p=2?q=1');
|
router.navigateByUrl('/a;p=2?q=1');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(count).toEqual(4);
|
expect(guardRunCount).toEqual(4);
|
||||||
|
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}]);
|
||||||
|
|
||||||
router.navigateByUrl('/a;p=2(right:b)?q=1');
|
router.navigateByUrl('/a;p=2(right:b)?q=1');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(count).toEqual(4);
|
expect(guardRunCount).toEqual(4);
|
||||||
|
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}]);
|
||||||
})));
|
})));
|
||||||
|
|
||||||
it('should always rerun guards',
|
it('should always rerun guards and resolvers',
|
||||||
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
|
fakeAsync(inject([Router], (router: Router) => {
|
||||||
const fixture = createRoot(router, RootCmpWithTwoOutlets);
|
const fixture = configureRouter(router, 'always');
|
||||||
|
|
||||||
router.resetConfig([
|
const cmp: RouteCmp = fixture.debugElement.children[1].componentInstance;
|
||||||
{
|
const recordedData: any[] = [];
|
||||||
path: 'a',
|
cmp.route.data.subscribe((data: any) => recordedData.push(data));
|
||||||
runGuardsAndResolvers: 'always',
|
|
||||||
component: SimpleCmp,
|
|
||||||
canActivate: ['loggingCanActivate']
|
|
||||||
},
|
|
||||||
{path: 'b', component: SimpleCmp, outlet: 'right'}
|
|
||||||
]);
|
|
||||||
|
|
||||||
router.navigateByUrl('/a');
|
expect(guardRunCount).toEqual(1);
|
||||||
advance(fixture);
|
expect(recordedData).toEqual([{data: 0}]);
|
||||||
expect(count).toEqual(1);
|
|
||||||
|
|
||||||
router.navigateByUrl('/a;p=1');
|
router.navigateByUrl('/a;p=1');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(count).toEqual(2);
|
expect(guardRunCount).toEqual(2);
|
||||||
|
expect(recordedData).toEqual([{data: 0}, {data: 1}]);
|
||||||
|
|
||||||
router.navigateByUrl('/a;p=2');
|
router.navigateByUrl('/a;p=2');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(count).toEqual(3);
|
expect(guardRunCount).toEqual(3);
|
||||||
|
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}]);
|
||||||
|
|
||||||
router.navigateByUrl('/a;p=2?q=1');
|
router.navigateByUrl('/a;p=2?q=1');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(count).toEqual(4);
|
expect(guardRunCount).toEqual(4);
|
||||||
|
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}]);
|
||||||
|
|
||||||
router.navigateByUrl('/a;p=2(right:b)?q=1');
|
router.navigateByUrl('/a;p=2(right:b)?q=1');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expect(count).toEqual(5);
|
expect(guardRunCount).toEqual(5);
|
||||||
|
expect(recordedData).toEqual([{data: 0}, {data: 1}, {data: 2}, {data: 3}, {data: 4}]);
|
||||||
})));
|
})));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue