Skip to content

Commit 9a0e681

Browse files
atscottAndrewKushnir
authored andcommitted
refactor(router): Extract router scroller into a tree-shakeable provider (angular#46215)
Extracting the scroller to a provider moves us towards thinking about a world where `ExtraOptions` doesn't exist to control behaviors that are opt-in/opt-out. Instead, these behaviors could be controlled by the presence (or lackthereof) of the providers which has the functionality. This is relevant to a world in which we no longer have the `RouterModule` but instead have something like `provideRouter` where the features are tree-shakeable. This change does not affect the current `RouterModule.forRoot` behavior, tree-shakeability of the option, or existence of the options related to the router scroller (scrollPositionRestoriation, anchorScrolling, scrollOffset). PR Close angular#46215
1 parent bfea80d commit 9a0e681

File tree

2 files changed

+22
-16
lines changed

2 files changed

+22
-16
lines changed

packages/router/src/router_module.ts

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {APP_BASE_HREF, HashLocationStrategy, Location, LOCATION_INITIALIZED, LocationStrategy, PathLocationStrategy, PlatformLocation, ViewportScroller} from '@angular/common';
10-
import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, ApplicationRef, Compiler, ComponentRef, ENVIRONMENT_INITIALIZER, Inject, inject, Injectable, InjectionToken, Injector, ModuleWithProviders, NgModule, NgProbeToken, OnDestroy, Optional, Provider, SkipSelf} from '@angular/core';
10+
import {ANALYZE_FOR_ENTRY_COMPONENTS, APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, ApplicationRef, Compiler, ComponentRef, ENVIRONMENT_INITIALIZER, Inject, inject, Injectable, InjectFlags, InjectionToken, Injector, ModuleWithProviders, NgModule, NgProbeToken, OnDestroy, Optional, Provider, SkipSelf} from '@angular/core';
1111
import {Title} from '@angular/platform-browser';
1212
import {of, Subject} from 'rxjs';
1313

@@ -23,7 +23,7 @@ import {ErrorHandler, Router} from './router';
2323
import {RouterConfigLoader, ROUTES} from './router_config_loader';
2424
import {ChildrenOutletContexts} from './router_outlet_context';
2525
import {NoPreloading, PreloadAllModules, PreloadingStrategy, RouterPreloader} from './router_preloader';
26-
import {RouterScroller} from './router_scroller';
26+
import {ROUTER_SCROLLER, RouterScroller} from './router_scroller';
2727
import {ActivatedRoute} from './router_state';
2828
import {UrlHandlingStrategy} from './url_handling_strategy';
2929
import {DefaultUrlSerializer, UrlSerializer, UrlTree} from './url_tree';
@@ -137,11 +137,7 @@ export class RouterModule {
137137
},
138138
{provide: ROUTER_CONFIGURATION, useValue: config ? config : {}},
139139
config?.useHash ? provideHashLocationStrategy() : providePathLocationStrategy(),
140-
{
141-
provide: RouterScroller,
142-
useFactory: createRouterScroller,
143-
deps: [Router, ViewportScroller, ROUTER_CONFIGURATION]
144-
},
140+
provideRouterScroller(),
145141
{
146142
provide: PreloadingStrategy,
147143
useExisting: config && config.preloadingStrategy ? config.preloadingStrategy :
@@ -174,12 +170,19 @@ export class RouterModule {
174170
}
175171
}
176172

177-
export function createRouterScroller(
178-
router: Router, viewportScroller: ViewportScroller, config: ExtraOptions): RouterScroller {
179-
if (config.scrollOffset) {
180-
viewportScroller.setOffset(config.scrollOffset);
181-
}
182-
return new RouterScroller(router, viewportScroller, config);
173+
export function provideRouterScroller(): Provider {
174+
return {
175+
provide: ROUTER_SCROLLER,
176+
useFactory: () => {
177+
const router = inject(Router);
178+
const viewportScroller = inject(ViewportScroller);
179+
const config: ExtraOptions = inject(ROUTER_CONFIGURATION);
180+
if (config.scrollOffset) {
181+
viewportScroller.setOffset(config.scrollOffset);
182+
}
183+
return new RouterScroller(router, viewportScroller, config);
184+
},
185+
};
183186
}
184187

185188
function provideHashLocationStrategy(): Provider {
@@ -573,7 +576,8 @@ export class RouterInitializer implements OnDestroy {
573576
bootstrapListener(bootstrappedComponentRef: ComponentRef<any>): void {
574577
const opts = this.injector.get(ROUTER_CONFIGURATION);
575578
const preloader = this.injector.get(RouterPreloader);
576-
const routerScroller = this.injector.get(RouterScroller);
579+
const routerScroller: RouterScroller|null =
580+
this.injector.get(ROUTER_SCROLLER, null, InjectFlags.Optional);
577581
const router = this.injector.get(Router);
578582
const ref = this.injector.get<ApplicationRef>(ApplicationRef);
579583

@@ -587,7 +591,7 @@ export class RouterInitializer implements OnDestroy {
587591
}
588592

589593
preloader.setUpPreloading();
590-
routerScroller.init();
594+
routerScroller?.init();
591595
router.resetRootComponentType(ref.componentTypes[0]);
592596
this.resultOfPreactivationDone.next(void 0);
593597
this.resultOfPreactivationDone.complete();

packages/router/src/router_scroller.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@
77
*/
88

99
import {ViewportScroller} from '@angular/common';
10-
import {Injectable, OnDestroy} from '@angular/core';
10+
import {Injectable, InjectionToken, OnDestroy} from '@angular/core';
1111
import {Unsubscribable} from 'rxjs';
1212

1313
import {NavigationEnd, NavigationStart, Scroll} from './events';
1414
import {Router} from './router';
1515

16+
export const ROUTER_SCROLLER = new InjectionToken<RouterScroller>('');
17+
1618
@Injectable()
1719
export class RouterScroller implements OnDestroy {
1820
// TODO(issue/24571): remove '!'.

0 commit comments

Comments
 (0)