refactor(router): Simplify router defaults by making the defaults Injectable (#48022)

The router has several default strategy implementations that are either
assigned via `new XStrategy()` property assignements or via the factory
function for the `Router` itself. These can be simplified by providing
the default implementation in the strategy `Injectable`. Custom
implementations can still override the defaults by specifying them in
the `providers` list.

Notably, this change also makes the `UrlHandlingStrategy` and
`RouteReuseStrategy` defaults injectable via DI rather than having to
indirectly grab them by going through the `Router` instance and
accessing the properties.

PR Close #48022
This commit is contained in:
Andrew Scott
2022-11-10 12:03:57 -08:00
committed by Dylan Hunn
parent 6732618399
commit 02b18dc5b0
6 changed files with 45 additions and 23 deletions
+8
View File
@@ -690,6 +690,10 @@ export abstract class RouteReuseStrategy {
abstract shouldDetach(route: ActivatedRouteSnapshot): boolean;
abstract shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean;
abstract store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle | null): void;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<RouteReuseStrategy, never>;
// (undocumented)
static ɵprov: i0.ɵɵInjectableDeclaration<RouteReuseStrategy>;
}
// @public
@@ -941,6 +945,10 @@ export abstract class UrlHandlingStrategy {
abstract extract(url: UrlTree): UrlTree;
abstract merge(newUrlPart: UrlTree, rawUrl: UrlTree): UrlTree;
abstract shouldProcessUrl(url: UrlTree): boolean;
// (undocumented)
static ɵfac: i0.ɵɵFactoryDeclaration<UrlHandlingStrategy, never>;
// (undocumented)
static ɵprov: i0.ɵɵInjectableDeclaration<UrlHandlingStrategy>;
}
// @public
@@ -33,7 +33,7 @@
"cli-hello-world-lazy": {
"uncompressed": {
"runtime": 2835,
"main": 225113,
"main": 225766,
"polyfills": 33842,
"src_app_lazy_lazy_routes_ts": 487
}
@@ -125,9 +125,15 @@
{
"name": "DefaultIfEmptySubscriber"
},
{
"name": "DefaultRouteReuseStrategy"
},
{
"name": "DefaultTitleStrategy"
},
{
"name": "DefaultUrlHandlingStrategy"
},
{
"name": "DefaultUrlSerializer"
},
@@ -464,6 +470,9 @@
{
"name": "RootViewRef"
},
{
"name": "RouteReuseStrategy"
},
{
"name": "RouteTitleKey"
},
@@ -617,6 +626,9 @@
{
"name": "UnsubscriptionError"
},
{
"name": "UrlHandlingStrategy"
},
{
"name": "UrlParser"
},
@@ -1088,6 +1100,9 @@
{
"name": "getFactoryDef"
},
{
"name": "getFactoryOf"
},
{
"name": "getFirstLContainer"
},
@@ -1346,6 +1361,9 @@
{
"name": "isEnvironmentProviders"
},
{
"name": "isForwardRef"
},
{
"name": "isFunction"
},
@@ -1526,6 +1544,9 @@
{
"name": "noMatch2"
},
{
"name": "noSideEffects"
},
{
"name": "nodeChildrenAsMap"
},
+5 -2
View File
@@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ComponentRef} from '@angular/core';
import {ComponentRef, inject, Injectable} from '@angular/core';
import {OutletContext} from './router_outlet_context';
import {ActivatedRoute, ActivatedRouteSnapshot} from './router_state';
@@ -38,6 +38,7 @@ export type DetachedRouteHandleInternal = {
*
* @publicApi
*/
@Injectable({providedIn: 'root', useFactory: () => inject(DefaultRouteReuseStrategy)})
export abstract class RouteReuseStrategy {
/** Determines if this route (and its subtree) should be detached to be reused later */
abstract shouldDetach(route: ActivatedRouteSnapshot): boolean;
@@ -110,4 +111,6 @@ export abstract class BaseRouteReuseStrategy implements RouteReuseStrategy {
}
}
export class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {}
@Injectable({providedIn: 'root'})
export class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
}
+6 -20
View File
@@ -23,14 +23,14 @@ import {checkGuards} from './operators/check_guards';
import {recognize} from './operators/recognize';
import {resolveData} from './operators/resolve_data';
import {switchTap} from './operators/switch_tap';
import {DefaultTitleStrategy, TitleStrategy} from './page_title_strategy';
import {DefaultRouteReuseStrategy, RouteReuseStrategy} from './route_reuse_strategy';
import {TitleStrategy} from './page_title_strategy';
import {RouteReuseStrategy} from './route_reuse_strategy';
import {ErrorHandler, ExtraOptions, ROUTER_CONFIGURATION} from './router_config';
import {RouterConfigLoader, ROUTES} from './router_config_loader';
import {ChildrenOutletContexts} from './router_outlet_context';
import {ActivatedRoute, ActivatedRouteSnapshot, createEmptyState, RouterState, RouterStateSnapshot} from './router_state';
import {Params} from './shared';
import {DefaultUrlHandlingStrategy, UrlHandlingStrategy} from './url_handling_strategy';
import {UrlHandlingStrategy} from './url_handling_strategy';
import {containsTree, IsActiveMatchOptions, isUrlTree, UrlSerializer, UrlTree} from './url_tree';
import {flatten} from './utils/collection';
import {standardizeConfig, validateConfig} from './utils/config';
@@ -325,23 +325,9 @@ export function setupRouter() {
const compiler = inject(Compiler);
const config = inject(ROUTES, {optional: true}) ?? [];
const opts = inject(ROUTER_CONFIGURATION, {optional: true}) ?? {};
const defaultTitleStrategy = inject(DefaultTitleStrategy);
const titleStrategy = inject(TitleStrategy, {optional: true});
const urlHandlingStrategy = inject(UrlHandlingStrategy, {optional: true});
const routeReuseStrategy = inject(RouteReuseStrategy, {optional: true});
const router =
new Router(null, urlSerializer, contexts, location, injector, compiler, flatten(config));
if (urlHandlingStrategy) {
router.urlHandlingStrategy = urlHandlingStrategy;
}
if (routeReuseStrategy) {
router.routeReuseStrategy = routeReuseStrategy;
}
router.titleStrategy = titleStrategy ?? defaultTitleStrategy;
assignExtraOptionsToRouter(opts, router);
return router;
@@ -475,17 +461,17 @@ export class Router {
* A strategy for extracting and merging URLs.
* Used for AngularJS to Angular migrations.
*/
urlHandlingStrategy: UrlHandlingStrategy = new DefaultUrlHandlingStrategy();
urlHandlingStrategy = inject(UrlHandlingStrategy);
/**
* A strategy for re-using routes.
*/
routeReuseStrategy: RouteReuseStrategy = new DefaultRouteReuseStrategy();
routeReuseStrategy = inject(RouteReuseStrategy);
/**
* A strategy for setting the title based on the `routerState`.
*/
titleStrategy?: TitleStrategy;
titleStrategy?: TitleStrategy = inject(TitleStrategy);
/**
* How to handle a navigation request to the current URL. One of:
@@ -6,6 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/
import {inject, Injectable} from '@angular/core';
import {UrlTree} from './url_tree';
/**
@@ -15,6 +17,7 @@ import {UrlTree} from './url_tree';
*
* @publicApi
*/
@Injectable({providedIn: 'root', useFactory: () => inject(DefaultUrlHandlingStrategy)})
export abstract class UrlHandlingStrategy {
/**
* Tells the router if this URL should be processed.
@@ -41,6 +44,7 @@ export abstract class UrlHandlingStrategy {
/**
* @publicApi
*/
@Injectable({providedIn: 'root'})
export class DefaultUrlHandlingStrategy implements UrlHandlingStrategy {
shouldProcessUrl(url: UrlTree): boolean {
return true;