Skip to content

Commit

Permalink
refactor(router): Simplify router defaults by making the defaults Inj…
Browse files Browse the repository at this point in the history
…ectable (#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
  • Loading branch information
atscott authored and dylhunn committed Nov 17, 2022
1 parent 6732618 commit 02b18dc
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 23 deletions.
8 changes: 8 additions & 0 deletions goldens/public-api/router/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion goldens/size-tracking/integration-payloads.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"cli-hello-world-lazy": {
"uncompressed": {
"runtime": 2835,
"main": 225113,
"main": 225766,
"polyfills": 33842,
"src_app_lazy_lazy_routes_ts": 487
}
Expand Down
21 changes: 21 additions & 0 deletions packages/core/test/bundling/router/bundle.golden_symbols.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,15 @@
{
"name": "DefaultIfEmptySubscriber"
},
{
"name": "DefaultRouteReuseStrategy"
},
{
"name": "DefaultTitleStrategy"
},
{
"name": "DefaultUrlHandlingStrategy"
},
{
"name": "DefaultUrlSerializer"
},
Expand Down Expand Up @@ -464,6 +470,9 @@
{
"name": "RootViewRef"
},
{
"name": "RouteReuseStrategy"
},
{
"name": "RouteTitleKey"
},
Expand Down Expand Up @@ -617,6 +626,9 @@
{
"name": "UnsubscriptionError"
},
{
"name": "UrlHandlingStrategy"
},
{
"name": "UrlParser"
},
Expand Down Expand Up @@ -1088,6 +1100,9 @@
{
"name": "getFactoryDef"
},
{
"name": "getFactoryOf"
},
{
"name": "getFirstLContainer"
},
Expand Down Expand Up @@ -1346,6 +1361,9 @@
{
"name": "isEnvironmentProviders"
},
{
"name": "isForwardRef"
},
{
"name": "isFunction"
},
Expand Down Expand Up @@ -1526,6 +1544,9 @@
{
"name": "noMatch2"
},
{
"name": "noSideEffects"
},
{
"name": "nodeChildrenAsMap"
},
Expand Down
7 changes: 5 additions & 2 deletions packages/router/src/route_reuse_strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -110,4 +111,6 @@ export abstract class BaseRouteReuseStrategy implements RouteReuseStrategy {
}
}

export class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {}
@Injectable({providedIn: 'root'})
export class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
}
26 changes: 6 additions & 20 deletions packages/router/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down
4 changes: 4 additions & 0 deletions packages/router/src/url_handling_strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand All @@ -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.
Expand All @@ -41,6 +44,7 @@ export abstract class UrlHandlingStrategy {
/**
* @publicApi
*/
@Injectable({providedIn: 'root'})
export class DefaultUrlHandlingStrategy implements UrlHandlingStrategy {
shouldProcessUrl(url: UrlTree): boolean {
return true;
Expand Down

0 comments on commit 02b18dc

Please sign in to comment.