mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
feat(router): Make router directives standalone (#46758)
This commit makes the router directives standalone and refactors some of the Router injectables to be `providedIn: 'root'` along with factory functions for initialization. PR Close #46758
This commit is contained in:
committed by
Jessica Janiuk
parent
4a81fe7d32
commit
26ea97688c
@@ -179,6 +179,10 @@ export class ChildrenOutletContexts {
|
||||
onOutletDeactivated(): Map<string, OutletContext>;
|
||||
// (undocumented)
|
||||
onOutletReAttached(contexts: Map<string, OutletContext>): void;
|
||||
// (undocumented)
|
||||
static ɵfac: i0.ɵɵFactoryDeclaration<ChildrenOutletContexts, never>;
|
||||
// (undocumented)
|
||||
static ɵprov: i0.ɵɵInjectableDeclaration<ChildrenOutletContexts>;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -666,7 +670,7 @@ export class RouterLink implements OnChanges {
|
||||
// (undocumented)
|
||||
get urlTree(): UrlTree | null;
|
||||
// (undocumented)
|
||||
static ɵdir: i0.ɵɵDirectiveDeclaration<RouterLink, ":not(a):not(area)[routerLink]", never, { "queryParams": "queryParams"; "fragment": "fragment"; "queryParamsHandling": "queryParamsHandling"; "preserveFragment": "preserveFragment"; "skipLocationChange": "skipLocationChange"; "replaceUrl": "replaceUrl"; "state": "state"; "relativeTo": "relativeTo"; "routerLink": "routerLink"; }, {}, never, never, false>;
|
||||
static ɵdir: i0.ɵɵDirectiveDeclaration<RouterLink, ":not(a):not(area)[routerLink]", never, { "queryParams": "queryParams"; "fragment": "fragment"; "queryParamsHandling": "queryParamsHandling"; "preserveFragment": "preserveFragment"; "skipLocationChange": "skipLocationChange"; "replaceUrl": "replaceUrl"; "state": "state"; "relativeTo": "relativeTo"; "routerLink": "routerLink"; }, {}, never, never, true>;
|
||||
// (undocumented)
|
||||
static ɵfac: i0.ɵɵFactoryDeclaration<RouterLink, [null, null, { attribute: "tabindex"; }, null, null]>;
|
||||
}
|
||||
@@ -694,7 +698,7 @@ export class RouterLinkActive implements OnChanges, OnDestroy, AfterContentInit
|
||||
exact: boolean;
|
||||
} | IsActiveMatchOptions;
|
||||
// (undocumented)
|
||||
static ɵdir: i0.ɵɵDirectiveDeclaration<RouterLinkActive, "[routerLinkActive]", ["routerLinkActive"], { "routerLinkActiveOptions": "routerLinkActiveOptions"; "ariaCurrentWhenActive": "ariaCurrentWhenActive"; "routerLinkActive": "routerLinkActive"; }, { "isActiveChange": "isActiveChange"; }, ["links", "linksWithHrefs"], never, false>;
|
||||
static ɵdir: i0.ɵɵDirectiveDeclaration<RouterLinkActive, "[routerLinkActive]", ["routerLinkActive"], { "routerLinkActiveOptions": "routerLinkActiveOptions"; "ariaCurrentWhenActive": "ariaCurrentWhenActive"; "routerLinkActive": "routerLinkActive"; }, { "isActiveChange": "isActiveChange"; }, ["links", "linksWithHrefs"], never, true>;
|
||||
// (undocumented)
|
||||
static ɵfac: i0.ɵɵFactoryDeclaration<RouterLinkActive, [null, null, null, null, { optional: true; }, { optional: true; }]>;
|
||||
}
|
||||
@@ -726,7 +730,7 @@ export class RouterLinkWithHref implements OnChanges, OnDestroy {
|
||||
// (undocumented)
|
||||
get urlTree(): UrlTree | null;
|
||||
// (undocumented)
|
||||
static ɵdir: i0.ɵɵDirectiveDeclaration<RouterLinkWithHref, "a[routerLink],area[routerLink]", never, { "target": "target"; "queryParams": "queryParams"; "fragment": "fragment"; "queryParamsHandling": "queryParamsHandling"; "preserveFragment": "preserveFragment"; "skipLocationChange": "skipLocationChange"; "replaceUrl": "replaceUrl"; "state": "state"; "relativeTo": "relativeTo"; "routerLink": "routerLink"; }, {}, never, never, false>;
|
||||
static ɵdir: i0.ɵɵDirectiveDeclaration<RouterLinkWithHref, "a[routerLink],area[routerLink]", never, { "target": "target"; "queryParams": "queryParams"; "fragment": "fragment"; "queryParamsHandling": "queryParamsHandling"; "preserveFragment": "preserveFragment"; "skipLocationChange": "skipLocationChange"; "replaceUrl": "replaceUrl"; "state": "state"; "relativeTo": "relativeTo"; "routerLink": "routerLink"; }, {}, never, never, true>;
|
||||
// (undocumented)
|
||||
static ɵfac: i0.ɵɵFactoryDeclaration<RouterLinkWithHref, never>;
|
||||
}
|
||||
@@ -741,7 +745,7 @@ export class RouterModule {
|
||||
// (undocumented)
|
||||
static ɵinj: i0.ɵɵInjectorDeclaration<RouterModule>;
|
||||
// (undocumented)
|
||||
static ɵmod: i0.ɵɵNgModuleDeclaration<RouterModule, [typeof i1.RouterOutlet, typeof i2.RouterLink, typeof i2.RouterLinkWithHref, typeof i3.RouterLinkActive, typeof i4.ɵEmptyOutletComponent], never, [typeof i1.RouterOutlet, typeof i2.RouterLink, typeof i2.RouterLinkWithHref, typeof i3.RouterLinkActive, typeof i4.ɵEmptyOutletComponent]>;
|
||||
static ɵmod: i0.ɵɵNgModuleDeclaration<RouterModule, never, [typeof i1.RouterOutlet, typeof i2.RouterLink, typeof i2.RouterLinkWithHref, typeof i3.RouterLinkActive, typeof i4.ɵEmptyOutletComponent], [typeof i1.RouterOutlet, typeof i2.RouterLink, typeof i2.RouterLinkWithHref, typeof i3.RouterLinkActive, typeof i4.ɵEmptyOutletComponent]>;
|
||||
}
|
||||
|
||||
// @public
|
||||
@@ -772,7 +776,7 @@ export class RouterOutlet implements OnDestroy, OnInit, RouterOutletContract {
|
||||
// (undocumented)
|
||||
ngOnInit(): void;
|
||||
// (undocumented)
|
||||
static ɵdir: i0.ɵɵDirectiveDeclaration<RouterOutlet, "router-outlet", ["outlet"], {}, { "activateEvents": "activate"; "deactivateEvents": "deactivate"; "attachEvents": "attach"; "detachEvents": "detach"; }, never, never, false>;
|
||||
static ɵdir: i0.ɵɵDirectiveDeclaration<RouterOutlet, "router-outlet", ["outlet"], {}, { "activateEvents": "activate"; "deactivateEvents": "deactivate"; "attachEvents": "attach"; "detachEvents": "detach"; }, never, never, true>;
|
||||
// (undocumented)
|
||||
static ɵfac: i0.ɵɵFactoryDeclaration<RouterOutlet, [null, null, { attribute: "name"; }, null, null]>;
|
||||
}
|
||||
@@ -942,6 +946,10 @@ export class UrlSegmentGroup {
|
||||
export abstract class UrlSerializer {
|
||||
abstract parse(url: string): UrlTree;
|
||||
abstract serialize(tree: UrlTree): string;
|
||||
// (undocumented)
|
||||
static ɵfac: i0.ɵɵFactoryDeclaration<UrlSerializer, never>;
|
||||
// (undocumented)
|
||||
static ɵprov: i0.ɵɵInjectableDeclaration<UrlSerializer>;
|
||||
}
|
||||
|
||||
// @public
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"aio-local": {
|
||||
"uncompressed": {
|
||||
"runtime": 4325,
|
||||
"main": 461893,
|
||||
"main": 462546,
|
||||
"polyfills": 33922,
|
||||
"styles": 73640,
|
||||
"light-theme": 78276,
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"cli-hello-world-lazy": {
|
||||
"uncompressed": {
|
||||
"runtime": 2835,
|
||||
"main": 237313,
|
||||
"main": 238214,
|
||||
"polyfills": 33842,
|
||||
"src_app_lazy_lazy_module_ts": 780
|
||||
}
|
||||
|
||||
@@ -620,6 +620,9 @@
|
||||
{
|
||||
"name": "SkipSelf"
|
||||
},
|
||||
{
|
||||
"name": "StandaloneService"
|
||||
},
|
||||
{
|
||||
"name": "Subject"
|
||||
},
|
||||
@@ -1970,6 +1973,9 @@
|
||||
{
|
||||
"name": "ɵɵNgOnChangesFeature"
|
||||
},
|
||||
{
|
||||
"name": "ɵɵStandaloneFeature"
|
||||
},
|
||||
{
|
||||
"name": "ɵɵattribute"
|
||||
},
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
import {RouterOutlet} from '../directives/router_outlet';
|
||||
|
||||
/**
|
||||
* This component is used internally within the router to be a placeholder when an empty
|
||||
* router-outlet is needed. For example, with a config such as:
|
||||
@@ -17,7 +19,11 @@ import {Component} from '@angular/core';
|
||||
* In order to render, there needs to be a component on this config, which will default
|
||||
* to this `EmptyOutletComponent`.
|
||||
*/
|
||||
@Component({template: `<router-outlet></router-outlet>`})
|
||||
@Component({
|
||||
template: `<router-outlet></router-outlet>`,
|
||||
imports: [RouterOutlet],
|
||||
standalone: true,
|
||||
})
|
||||
export class ɵEmptyOutletComponent {
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +115,10 @@ import {UrlTree} from '../url_tree';
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
@Directive({selector: ':not(a):not(area)[routerLink]'})
|
||||
@Directive({
|
||||
selector: ':not(a):not(area)[routerLink]',
|
||||
standalone: true,
|
||||
})
|
||||
export class RouterLink implements OnChanges {
|
||||
/**
|
||||
* Passed to {@link Router#createUrlTree Router#createUrlTree} as part of the
|
||||
@@ -277,7 +280,7 @@ export class RouterLink implements OnChanges {
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
@Directive({selector: 'a[routerLink],area[routerLink]'})
|
||||
@Directive({selector: 'a[routerLink],area[routerLink]', standalone: true})
|
||||
export class RouterLinkWithHref implements OnChanges, OnDestroy {
|
||||
// TODO(issue/24571): remove '!'.
|
||||
@HostBinding('attr.target') @Input() target!: string;
|
||||
|
||||
@@ -89,6 +89,7 @@ import {RouterLink, RouterLinkWithHref} from './router_link';
|
||||
@Directive({
|
||||
selector: '[routerLinkActive]',
|
||||
exportAs: 'routerLinkActive',
|
||||
standalone: true,
|
||||
})
|
||||
export class RouterLinkActive implements OnChanges, OnDestroy, AfterContentInit {
|
||||
@ContentChildren(RouterLink, {descendants: true}) links!: QueryList<RouterLink>;
|
||||
|
||||
@@ -157,7 +157,11 @@ export interface RouterOutletContract {
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
@Directive({selector: 'router-outlet', exportAs: 'outlet'})
|
||||
@Directive({
|
||||
selector: 'router-outlet',
|
||||
exportAs: 'outlet',
|
||||
standalone: true,
|
||||
})
|
||||
export class RouterOutlet implements OnDestroy, OnInit, RouterOutletContract {
|
||||
private activated: ComponentRef<any>|null = null;
|
||||
private _activatedRoute: ActivatedRoute|null = null;
|
||||
|
||||
@@ -31,7 +31,7 @@ export const ROUTES = new InjectionToken<Route[][]>('ROUTES');
|
||||
|
||||
type ComponentLoader = Observable<Type<unknown>>;
|
||||
|
||||
@Injectable()
|
||||
@Injectable({providedIn: 'root'})
|
||||
export class RouterConfigLoader {
|
||||
private componentLoaders = new WeakMap<Route, ComponentLoader>();
|
||||
private childrenLoaders = new WeakMap<Route, Observable<LoadedRouterConfig>>();
|
||||
|
||||
@@ -74,6 +74,10 @@ export const ROUTER_PROVIDERS: Provider[] = [
|
||||
RouterConfigLoader,
|
||||
];
|
||||
|
||||
export function rootRoute(router: Router): ActivatedRoute {
|
||||
return router.routerState.root;
|
||||
}
|
||||
|
||||
export function routerNgProbeToken() {
|
||||
return new NgProbeToken('Router', Router);
|
||||
}
|
||||
@@ -100,7 +104,7 @@ export function routerNgProbeToken() {
|
||||
* @publicApi
|
||||
*/
|
||||
@NgModule({
|
||||
declarations: ROUTER_DIRECTIVES,
|
||||
imports: ROUTER_DIRECTIVES,
|
||||
exports: ROUTER_DIRECTIVES,
|
||||
})
|
||||
export class RouterModule {
|
||||
@@ -512,10 +516,6 @@ export function assignExtraOptionsToRouter(opts: ExtraOptions, router: Router):
|
||||
}
|
||||
}
|
||||
|
||||
export function rootRoute(router: Router): ActivatedRoute {
|
||||
return router.routerState.root;
|
||||
}
|
||||
|
||||
export function getBootstrapListener() {
|
||||
const injector = inject(Injector);
|
||||
return (bootstrappedComponentRef: ComponentRef<unknown>) => {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ComponentFactoryResolver, ComponentRef, EnvironmentInjector} from '@angular/core';
|
||||
import {ComponentFactoryResolver, ComponentRef, EnvironmentInjector, Injectable} from '@angular/core';
|
||||
|
||||
import {RouterOutletContract} from './directives/router_outlet';
|
||||
import {ActivatedRoute} from './router_state';
|
||||
@@ -35,6 +35,7 @@ export class OutletContext {
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
@Injectable({providedIn: 'root'})
|
||||
export class ChildrenOutletContexts {
|
||||
// contexts for child outlets, by name.
|
||||
private contexts = new Map<string, OutletContext>();
|
||||
|
||||
@@ -16,8 +16,6 @@ import {equalSegments, UrlSegment, UrlSegmentGroup, UrlTree} from './url_tree';
|
||||
import {shallowEqual, shallowEqualArrays} from './utils/collection';
|
||||
import {Tree, TreeNode} from './utils/tree';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Represents the state of the router as a tree of activated routes.
|
||||
*
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ɵRuntimeError as RuntimeError} from '@angular/core';
|
||||
import {Injectable, ɵRuntimeError as RuntimeError} from '@angular/core';
|
||||
|
||||
import {RuntimeErrorCode} from './errors';
|
||||
import {convertToParamMap, ParamMap, Params, PRIMARY_OUTLET} from './shared';
|
||||
@@ -356,6 +356,7 @@ export function mapChildrenIntoArray<T>(
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
@Injectable({providedIn: 'root', useFactory: () => new DefaultUrlSerializer()})
|
||||
export abstract class UrlSerializer {
|
||||
/** Parse a url into a `UrlTree` */
|
||||
abstract parse(url: string): UrlTree;
|
||||
|
||||
Reference in New Issue
Block a user