From e95ee96562d3fd2a7422ca293c03da35cb0e8a8b Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Mon, 18 Jul 2022 13:23:50 -0700 Subject: [PATCH] refactor(router): Update TitleStrategy to useFactory (#46876) The implementation of the `DefaultTitleStrategy` was modeled after the existing strategy patterns in the Router. These patterns were developed before the `providedIn` syntax for injectables. We can simplify the model a lot by providing the default in the factory of the abstract class. Note that the other strategy patterns aren't touched in this PR due to how long they've existed. Because they have been there for such a long time, it's possible there will need to be some adjustments to code if/when they are refactored to do the same. PR Close #46876 --- goldens/public-api/router/index.md | 4 ++++ goldens/public-api/router/testing/index.md | 3 +-- packages/router/src/page_title_strategy.ts | 3 ++- packages/router/src/router_module.ts | 16 ++++++------- .../testing/src/router_testing_module.ts | 23 +++++++++++-------- 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/goldens/public-api/router/index.md b/goldens/public-api/router/index.md index ca068bebfd4..4559e465589 100644 --- a/goldens/public-api/router/index.md +++ b/goldens/public-api/router/index.md @@ -874,6 +874,10 @@ export abstract class TitleStrategy { buildTitle(snapshot: RouterStateSnapshot): string | undefined; getResolvedTitleForRoute(snapshot: ActivatedRouteSnapshot): any; abstract updateTitle(snapshot: RouterStateSnapshot): void; + // (undocumented) + static ɵfac: i0.ɵɵFactoryDeclaration; + // (undocumented) + static ɵprov: i0.ɵɵInjectableDeclaration; } // @public diff --git a/goldens/public-api/router/testing/index.md b/goldens/public-api/router/testing/index.md index 7de12c46fcc..b7364f3331d 100644 --- a/goldens/public-api/router/testing/index.md +++ b/goldens/public-api/router/testing/index.md @@ -6,7 +6,6 @@ import { ChildrenOutletContexts } from '@angular/router'; import { Compiler } from '@angular/core'; -import { DefaultTitleStrategy } from '@angular/router'; import { ExtraOptions } from '@angular/router'; import * as i0 from '@angular/core'; import * as i1 from '@angular/router'; @@ -37,7 +36,7 @@ export class RouterTestingModule { export function setupTestingRouter(urlSerializer: UrlSerializer, contexts: ChildrenOutletContexts, location: Location_2, compiler: Compiler, injector: Injector, routes: Route[][], opts?: ExtraOptions | UrlHandlingStrategy | null, urlHandlingStrategy?: UrlHandlingStrategy, routeReuseStrategy?: RouteReuseStrategy, titleStrategy?: TitleStrategy): Router; // @public -export function setupTestingRouterInternal(urlSerializer: UrlSerializer, contexts: ChildrenOutletContexts, location: Location_2, compiler: Compiler, injector: Injector, routes: Route[][], opts?: ExtraOptions | UrlHandlingStrategy, urlHandlingStrategy?: UrlHandlingStrategy, routeReuseStrategy?: RouteReuseStrategy, defaultTitleStrategy?: DefaultTitleStrategy, titleStrategy?: TitleStrategy): Router; +export function setupTestingRouterInternal(urlSerializer: UrlSerializer, contexts: ChildrenOutletContexts, location: Location_2, compiler: Compiler, injector: Injector, routes: Route[][], titleStrategy: TitleStrategy, opts?: ExtraOptions | UrlHandlingStrategy, urlHandlingStrategy?: UrlHandlingStrategy, routeReuseStrategy?: RouteReuseStrategy): Router; // (No @packageDocumentation comment for this package) diff --git a/packages/router/src/page_title_strategy.ts b/packages/router/src/page_title_strategy.ts index 2663dd55da3..aead414744a 100644 --- a/packages/router/src/page_title_strategy.ts +++ b/packages/router/src/page_title_strategy.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Injectable} from '@angular/core'; +import {inject, Injectable} from '@angular/core'; import {Title} from '@angular/platform-browser'; import {RouteTitle as TitleKey} from './operators/resolve_data'; @@ -36,6 +36,7 @@ import {PRIMARY_OUTLET} from './shared'; * @publicApi * @see [Page title guide](guide/router#setting-the-page-title) */ +@Injectable({providedIn: 'root', useFactory: () => inject(DefaultTitleStrategy)}) export abstract class TitleStrategy { /** Performs the application title update. */ abstract updateTitle(snapshot: RouterStateSnapshot): void; diff --git a/packages/router/src/router_module.ts b/packages/router/src/router_module.ts index c02ca03e21f..3f4ba516c9b 100644 --- a/packages/router/src/router_module.ts +++ b/packages/router/src/router_module.ts @@ -18,7 +18,7 @@ import {RouterOutlet} from './directives/router_outlet'; import {RuntimeErrorCode} from './errors'; import {Event, NavigationCancel, NavigationCancellationCode, NavigationEnd, NavigationError, stringifyEvent} from './events'; import {Route, Routes} from './models'; -import {DefaultTitleStrategy, TitleStrategy} from './page_title_strategy'; +import {TitleStrategy} from './page_title_strategy'; import {RouteReuseStrategy} from './route_reuse_strategy'; import {ErrorHandler, Router} from './router'; import {RouterConfigLoader, ROUTES} from './router_config_loader'; @@ -64,9 +64,9 @@ export const ROUTER_PROVIDERS: Provider[] = [ provide: Router, useFactory: setupRouter, deps: [ - UrlSerializer, ChildrenOutletContexts, Location, Injector, Compiler, ROUTES, - ROUTER_CONFIGURATION, DefaultTitleStrategy, [TitleStrategy, new Optional()], - [UrlHandlingStrategy, new Optional()], [RouteReuseStrategy, new Optional()] + UrlSerializer, ChildrenOutletContexts, Location, Injector, Compiler, ROUTES, TitleStrategy, + ROUTER_CONFIGURATION, [UrlHandlingStrategy, new Optional()], + [RouteReuseStrategy, new Optional()] ] }, ChildrenOutletContexts, @@ -461,9 +461,9 @@ export interface ExtraOptions { export function setupRouter( urlSerializer: UrlSerializer, contexts: ChildrenOutletContexts, location: Location, - injector: Injector, compiler: Compiler, config: Route[][], opts: ExtraOptions = {}, - defaultTitleStrategy: DefaultTitleStrategy, titleStrategy?: TitleStrategy, - urlHandlingStrategy?: UrlHandlingStrategy, routeReuseStrategy?: RouteReuseStrategy) { + injector: Injector, compiler: Compiler, config: Route[][], titleStrategy: TitleStrategy, + opts: ExtraOptions = {}, urlHandlingStrategy?: UrlHandlingStrategy, + routeReuseStrategy?: RouteReuseStrategy) { const router = new Router(null, urlSerializer, contexts, location, injector, compiler, flatten(config)); @@ -475,7 +475,7 @@ export function setupRouter( router.routeReuseStrategy = routeReuseStrategy; } - router.titleStrategy = titleStrategy ?? defaultTitleStrategy; + router.titleStrategy = titleStrategy; assignExtraOptionsToRouter(opts, router); diff --git a/packages/router/testing/src/router_testing_module.ts b/packages/router/testing/src/router_testing_module.ts index 1362d0fb153..a1dff7143c3 100644 --- a/packages/router/testing/src/router_testing_module.ts +++ b/packages/router/testing/src/router_testing_module.ts @@ -9,7 +9,7 @@ import {Location, LocationStrategy} from '@angular/common'; import {MockLocationStrategy, SpyLocation} from '@angular/common/testing'; import {Compiler, Injector, ModuleWithProviders, NgModule, Optional} from '@angular/core'; -import {ChildrenOutletContexts, DefaultTitleStrategy, ExtraOptions, NoPreloading, PreloadingStrategy, provideRoutes, Route, Router, ROUTER_CONFIGURATION, RouteReuseStrategy, RouterModule, ROUTES, Routes, TitleStrategy, UrlHandlingStrategy, UrlSerializer, ɵassignExtraOptionsToRouter as assignExtraOptionsToRouter, ɵflatten as flatten, ɵprovidePreloading as providePreloading, ɵROUTER_PROVIDERS as ROUTER_PROVIDERS} from '@angular/router'; +import {ChildrenOutletContexts, ExtraOptions, NoPreloading, provideRoutes, Route, Router, ROUTER_CONFIGURATION, RouteReuseStrategy, RouterModule, ROUTES, Routes, TitleStrategy, UrlHandlingStrategy, UrlSerializer, ɵassignExtraOptionsToRouter as assignExtraOptionsToRouter, ɵflatten as flatten, ɵprovidePreloading as providePreloading, ɵROUTER_PROVIDERS as ROUTER_PROVIDERS} from '@angular/router'; import {EXTRA_ROUTER_TESTING_PROVIDERS} from './extra_router_testing_providers'; @@ -25,14 +25,20 @@ function isUrlHandlingStrategy(opts: ExtraOptions| * marked as publicApi cleaner (i.e. not having _both_ `TitleStrategy` and `DefaultTitleStrategy`). */ export function setupTestingRouterInternal( - urlSerializer: UrlSerializer, contexts: ChildrenOutletContexts, location: Location, - compiler: Compiler, injector: Injector, routes: Route[][], - opts?: ExtraOptions|UrlHandlingStrategy, urlHandlingStrategy?: UrlHandlingStrategy, - routeReuseStrategy?: RouteReuseStrategy, defaultTitleStrategy?: DefaultTitleStrategy, - titleStrategy?: TitleStrategy) { + urlSerializer: UrlSerializer, + contexts: ChildrenOutletContexts, + location: Location, + compiler: Compiler, + injector: Injector, + routes: Route[][], + titleStrategy: TitleStrategy, + opts?: ExtraOptions|UrlHandlingStrategy, + urlHandlingStrategy?: UrlHandlingStrategy, + routeReuseStrategy?: RouteReuseStrategy, +) { return setupTestingRouter( urlSerializer, contexts, location, compiler, injector, routes, opts, urlHandlingStrategy, - routeReuseStrategy, titleStrategy ?? defaultTitleStrategy); + routeReuseStrategy, titleStrategy); } /** @@ -112,11 +118,10 @@ export function setupTestingRouter( Compiler, Injector, ROUTES, + TitleStrategy, ROUTER_CONFIGURATION, [UrlHandlingStrategy, new Optional()], [RouteReuseStrategy, new Optional()], - [DefaultTitleStrategy, new Optional()], - [TitleStrategy, new Optional()], ] }, providePreloading(NoPreloading),