feat(router): add "onSameUrlNavigation" router configuration option (#19463)
PR Close #19463
This commit is contained in:
parent
adab4f3e49
commit
d3211a2468
|
@ -241,6 +241,14 @@ export class Router {
|
||||||
|
|
||||||
routeReuseStrategy: RouteReuseStrategy = new DefaultRouteReuseStrategy();
|
routeReuseStrategy: RouteReuseStrategy = new DefaultRouteReuseStrategy();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define what the router should do if it receives a navigation request to the current URL.
|
||||||
|
* By default, the router will ignore this navigation. However, this prevents features such
|
||||||
|
* as a "refresh" button. Use this option to configure the behavior when navigating to the
|
||||||
|
* current URL. Default is 'ignore'.
|
||||||
|
*/
|
||||||
|
onSameUrlNavigation: 'reload'|'ignore' = 'ignore';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the router service.
|
* Creates the router service.
|
||||||
*/
|
*/
|
||||||
|
@ -552,7 +560,8 @@ export class Router {
|
||||||
const url = this.urlHandlingStrategy.extract(rawUrl);
|
const url = this.urlHandlingStrategy.extract(rawUrl);
|
||||||
const urlTransition = !this.navigated || url.toString() !== this.currentUrlTree.toString();
|
const urlTransition = !this.navigated || url.toString() !== this.currentUrlTree.toString();
|
||||||
|
|
||||||
if (this.urlHandlingStrategy.shouldProcessUrl(rawUrl)) {
|
if ((this.onSameUrlNavigation === 'reload' ? true : urlTransition) &&
|
||||||
|
this.urlHandlingStrategy.shouldProcessUrl(rawUrl)) {
|
||||||
(this.events as Subject<Event>).next(new NavigationStart(id, this.serializeUrl(url)));
|
(this.events as Subject<Event>).next(new NavigationStart(id, this.serializeUrl(url)));
|
||||||
Promise.resolve()
|
Promise.resolve()
|
||||||
.then(
|
.then(
|
||||||
|
|
|
@ -129,12 +129,15 @@ export class RouterModule {
|
||||||
* Creates a module with all the router providers and directives. It also optionally sets up an
|
* Creates a module with all the router providers and directives. It also optionally sets up an
|
||||||
* application listener to perform an initial navigation.
|
* application listener to perform an initial navigation.
|
||||||
*
|
*
|
||||||
* Options:
|
* Options (see {@link ExtraOptions}):
|
||||||
* * `enableTracing` makes the router log all its internal events to the console.
|
* * `enableTracing` makes the router log all its internal events to the console.
|
||||||
* * `useHash` enables the location strategy that uses the URL fragment instead of the history
|
* * `useHash` enables the location strategy that uses the URL fragment instead of the history
|
||||||
* API.
|
* API.
|
||||||
* * `initialNavigation` disables the initial navigation.
|
* * `initialNavigation` disables the initial navigation.
|
||||||
* * `errorHandler` provides a custom error handler.
|
* * `errorHandler` provides a custom error handler.
|
||||||
|
* * `preloadingStrategy` configures a preloading strategy (see {@link PreloadAllModules}).
|
||||||
|
* * `onSameUrlNavigation` configures how the router handles navigation to the current URL. See
|
||||||
|
* {@link ExtraOptions} for more details.
|
||||||
*/
|
*/
|
||||||
static forRoot(routes: Routes, config?: ExtraOptions): ModuleWithProviders {
|
static forRoot(routes: Routes, config?: ExtraOptions): ModuleWithProviders {
|
||||||
return {
|
return {
|
||||||
|
@ -267,6 +270,14 @@ export interface ExtraOptions {
|
||||||
* Configures a preloading strategy. See {@link PreloadAllModules}.
|
* Configures a preloading strategy. See {@link PreloadAllModules}.
|
||||||
*/
|
*/
|
||||||
preloadingStrategy?: any;
|
preloadingStrategy?: any;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define what the router should do if it receives a navigation request to the current URL.
|
||||||
|
* By default, the router will ignore this navigation. However, this prevents features such
|
||||||
|
* as a "refresh" button. Use this option to configure the behavior when navigating to the
|
||||||
|
* current URL. Default is 'ignore'.
|
||||||
|
*/
|
||||||
|
onSameUrlNavigation?: 'reload'|'ignore';
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setupRouter(
|
export function setupRouter(
|
||||||
|
@ -299,6 +310,10 @@ export function setupRouter(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opts.onSameUrlNavigation) {
|
||||||
|
router.onSameUrlNavigation = opts.onSameUrlNavigation;
|
||||||
|
}
|
||||||
|
|
||||||
return router;
|
return router;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ describe('Integration', () => {
|
||||||
|
|
||||||
describe('navigation', function() {
|
describe('navigation', function() {
|
||||||
it('should navigate to the current URL', fakeAsync(inject([Router], (router: Router) => {
|
it('should navigate to the current URL', fakeAsync(inject([Router], (router: Router) => {
|
||||||
|
router.onSameUrlNavigation = 'reload';
|
||||||
router.resetConfig([
|
router.resetConfig([
|
||||||
{path: '', component: SimpleCmp},
|
{path: '', component: SimpleCmp},
|
||||||
{path: 'simple', component: SimpleCmp},
|
{path: 'simple', component: SimpleCmp},
|
||||||
|
@ -3568,30 +3569,34 @@ describe('Integration', () => {
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
const events: any[] = [];
|
const events: any[] = [];
|
||||||
router.events.subscribe(e => onlyNavigationStartAndEnd(e) && events.push(e));
|
router.events.subscribe(e => e instanceof RouterEvent && events.push(e));
|
||||||
|
|
||||||
location.go('/include/user/kate(aux:excluded)');
|
location.go('/include/user/kate(aux:excluded)');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
|
|
||||||
expect(location.path()).toEqual('/include/user/kate(aux:excluded)');
|
expect(location.path()).toEqual('/include/user/kate(aux:excluded)');
|
||||||
expectEvents(
|
expectEvents(events, [
|
||||||
events,
|
[NavigationStart, '/include/user/kate'], [RoutesRecognized, '/include/user/kate'],
|
||||||
[[NavigationStart, '/include/user/kate'], [NavigationEnd, '/include/user/kate']]);
|
[GuardsCheckStart, '/include/user/kate'], [GuardsCheckEnd, '/include/user/kate'],
|
||||||
|
[ResolveStart, '/include/user/kate'], [ResolveEnd, '/include/user/kate'],
|
||||||
|
[NavigationEnd, '/include/user/kate']
|
||||||
|
]);
|
||||||
events.splice(0);
|
events.splice(0);
|
||||||
|
|
||||||
location.go('/include/user/kate(aux:excluded2)');
|
location.go('/include/user/kate(aux:excluded2)');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
expectEvents(
|
expectEvents(events, []);
|
||||||
events,
|
|
||||||
[[NavigationStart, '/include/user/kate'], [NavigationEnd, '/include/user/kate']]);
|
|
||||||
events.splice(0);
|
|
||||||
|
|
||||||
router.navigateByUrl('/include/simple');
|
router.navigateByUrl('/include/simple');
|
||||||
advance(fixture);
|
advance(fixture);
|
||||||
|
|
||||||
expect(location.path()).toEqual('/include/simple(aux:excluded2)');
|
expect(location.path()).toEqual('/include/simple(aux:excluded2)');
|
||||||
expectEvents(
|
expectEvents(events, [
|
||||||
events, [[NavigationStart, '/include/simple'], [NavigationEnd, '/include/simple']]);
|
[NavigationStart, '/include/simple'], [RoutesRecognized, '/include/simple'],
|
||||||
|
[GuardsCheckStart, '/include/simple'], [GuardsCheckEnd, '/include/simple'],
|
||||||
|
[ResolveStart, '/include/simple'], [ResolveEnd, '/include/simple'],
|
||||||
|
[NavigationEnd, '/include/simple']
|
||||||
|
]);
|
||||||
})));
|
})));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -126,6 +126,7 @@ export interface ExtraOptions {
|
||||||
enableTracing?: boolean;
|
enableTracing?: boolean;
|
||||||
errorHandler?: ErrorHandler;
|
errorHandler?: ErrorHandler;
|
||||||
initialNavigation?: InitialNavigation;
|
initialNavigation?: InitialNavigation;
|
||||||
|
onSameUrlNavigation?: 'reload' | 'ignore';
|
||||||
preloadingStrategy?: any;
|
preloadingStrategy?: any;
|
||||||
useHash?: boolean;
|
useHash?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -327,6 +328,7 @@ export declare class Router {
|
||||||
errorHandler: ErrorHandler;
|
errorHandler: ErrorHandler;
|
||||||
readonly events: Observable<Event>;
|
readonly events: Observable<Event>;
|
||||||
navigated: boolean;
|
navigated: boolean;
|
||||||
|
onSameUrlNavigation: 'reload' | 'ignore';
|
||||||
routeReuseStrategy: RouteReuseStrategy;
|
routeReuseStrategy: RouteReuseStrategy;
|
||||||
readonly routerState: RouterState;
|
readonly routerState: RouterState;
|
||||||
readonly url: string;
|
readonly url: string;
|
||||||
|
|
Loading…
Reference in New Issue