fix(router): add relativeLinkResolution to recognize operator (#26990)

Close #26983

PR Close #26990
This commit is contained in:
Sarun Intaralawan 2018-11-08 04:18:08 +07:00 committed by Andrew Kushnir
parent 4348c472d6
commit d3044271dc
3 changed files with 91 additions and 5 deletions

View File

@ -17,13 +17,13 @@ import {UrlTree} from '../url_tree';
export function recognize( export function recognize(
rootComponentType: Type<any>| null, config: Route[], serializer: (url: UrlTree) => string, rootComponentType: Type<any>| null, config: Route[], serializer: (url: UrlTree) => string,
paramsInheritanceStrategy: 'emptyOnly' | paramsInheritanceStrategy: 'emptyOnly' | 'always', relativeLinkResolution: 'legacy' |
'always'): MonoTypeOperatorFunction<NavigationTransition> { 'corrected'): MonoTypeOperatorFunction<NavigationTransition> {
return function(source: Observable<NavigationTransition>) { return function(source: Observable<NavigationTransition>) {
return source.pipe(mergeMap( return source.pipe(mergeMap(
t => recognizeFn( t => recognizeFn(
rootComponentType, config, t.urlAfterRedirects, serializer(t.urlAfterRedirects), rootComponentType, config, t.urlAfterRedirects, serializer(t.urlAfterRedirects),
paramsInheritanceStrategy) paramsInheritanceStrategy, relativeLinkResolution)
.pipe(map(targetSnapshot => ({...t, targetSnapshot}))))); .pipe(map(targetSnapshot => ({...t, targetSnapshot})))));
}; };
} }

View File

@ -413,7 +413,7 @@ export class Router {
// Recognize // Recognize
recognize( recognize(
this.rootComponentType, this.config, (url) => this.serializeUrl(url), this.rootComponentType, this.config, (url) => this.serializeUrl(url),
this.paramsInheritanceStrategy), this.paramsInheritanceStrategy, this.relativeLinkResolution),
// Fire RoutesRecognized // Fire RoutesRecognized
tap(t => { tap(t => {

View File

@ -76,6 +76,41 @@ describe('Integration', () => {
]); ]);
}))); })));
describe('relativeLinkResolution', () => {
beforeEach(inject([Router], (router: Router) => {
router.resetConfig([{
path: 'foo',
children: [{path: 'bar', children: [{path: '', component: RelativeLinkCmp}]}]
}]);
}));
it('should not ignore empty paths in legacy mode',
fakeAsync(inject([Router], (router: Router) => {
router.relativeLinkResolution = 'legacy';
const fixture = createRoot(router, RootCmp);
router.navigateByUrl('/foo/bar');
advance(fixture);
const link = fixture.nativeElement.querySelector('a');
expect(link.getAttribute('href')).toEqual('/foo/bar/simple');
})));
it('should ignore empty paths in corrected mode',
fakeAsync(inject([Router], (router: Router) => {
router.relativeLinkResolution = 'corrected';
const fixture = createRoot(router, RootCmp);
router.navigateByUrl('/foo/bar');
advance(fixture);
const link = fixture.nativeElement.querySelector('a');
expect(link.getAttribute('href')).toEqual('/foo/simple');
})));
});
it('should set the restoredState to null when executing imperative navigations', it('should set the restoredState to null when executing imperative navigations',
fakeAsync(inject([Router], (router: Router) => { fakeAsync(inject([Router], (router: Router) => {
router.resetConfig([ router.resetConfig([
@ -3977,6 +4012,57 @@ describe('Integration', () => {
]); ]);
}))); })));
}); });
describe('relativeLinkResolution', () => {
@Component({selector: 'link-cmp', template: `<a [routerLink]="['../simple']">link</a>`})
class RelativeLinkCmp {
}
@NgModule({
declarations: [RelativeLinkCmp],
imports: [RouterModule.forChild([
{path: 'foo/bar', children: [{path: '', component: RelativeLinkCmp}]},
])]
})
class LazyLoadedModule {
}
it('should not ignore empty path when in legacy mode',
fakeAsync(inject(
[Router, NgModuleFactoryLoader],
(router: Router, loader: SpyNgModuleFactoryLoader) => {
router.relativeLinkResolution = 'legacy';
loader.stubbedModules = {expected: LazyLoadedModule};
const fixture = createRoot(router, RootCmp);
router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]);
router.navigateByUrl('/lazy/foo/bar');
advance(fixture);
const link = fixture.nativeElement.querySelector('a');
expect(link.getAttribute('href')).toEqual('/lazy/foo/bar/simple');
})));
it('should ignore empty path when in corrected mode',
fakeAsync(inject(
[Router, NgModuleFactoryLoader],
(router: Router, loader: SpyNgModuleFactoryLoader) => {
router.relativeLinkResolution = 'corrected';
loader.stubbedModules = {expected: LazyLoadedModule};
const fixture = createRoot(router, RootCmp);
router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]);
router.navigateByUrl('/lazy/foo/bar');
advance(fixture);
const link = fixture.nativeElement.querySelector('a');
expect(link.getAttribute('href')).toEqual('/lazy/foo/simple');
})));
});
}); });
describe('Custom Route Reuse Strategy', () => { describe('Custom Route Reuse Strategy', () => {