Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions packages/router/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@
* found in the LICENSE file at https://angular.io/license
*/


export {createUrlTreeFromSnapshot} from './create_url_tree';
export {RouterLink, RouterLinkWithHref} from './directives/router_link';
export {RouterLinkActive} from './directives/router_link_active';
export {RouterOutlet, RouterOutletContract} from './directives/router_outlet';
export {ActivationEnd, ActivationStart, ChildActivationEnd, ChildActivationStart, Event, EventType, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationCancellationCode as NavigationCancellationCode, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouterEvent, RoutesRecognized, Scroll} from './events';
export {CanActivate, CanActivateChild, CanActivateChildFn, CanActivateFn, CanDeactivate, CanDeactivateFn, CanLoad, CanLoadFn, CanMatch, CanMatchFn, Data, LoadChildren, LoadChildrenCallback, NavigationBehaviorOptions, QueryParamsHandling, Resolve, ResolveData, ResolveFn, Route, Routes, RunGuardsAndResolvers, UrlMatcher, UrlMatchResult} from './models';
export {DefaultTitleStrategy, TitleStrategy} from './page_title_strategy';
export {DebugTracingFeature, DisabledInitialNavigationFeature, EnabledBlockingInitialNavigationFeature, InitialNavigationFeature, InMemoryScrollingFeature, PreloadingFeature, provideRouter, provideRoutes, RouterConfigurationFeature, RouterFeature, RouterFeatures, withDebugTracing, withDisabledInitialNavigation, withEnabledBlockingInitialNavigation, withInMemoryScrolling, withPreloading, withRouterConfig} from './provide_router';
export {DebugTracingFeature, DisabledInitialNavigationFeature, EnabledBlockingInitialNavigationFeature, InitialNavigationFeature, InMemoryScrollingFeature, PreloadingFeature, provideRouter, provideRoutes, RouterConfigurationFeature, RouterFeature, RouterFeatures, withDebugTracing, withDisabledInitialNavigation, withEnabledBlockingInitialNavigation, withInMemoryScrolling, withLocationStrategy, withPreloading, withRouterConfig} from './provide_router';
export {BaseRouteReuseStrategy, DetachedRouteHandle, RouteReuseStrategy} from './route_reuse_strategy';
export {Navigation, NavigationExtras, Router, UrlCreationOptions} from './router';
export {ExtraOptions, InitialNavigation, InMemoryScrollingOptions, ROUTER_CONFIGURATION, RouterConfigOptions} from './router_config';
Expand Down
3 changes: 1 addition & 2 deletions packages/router/src/private_export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/


export {ɵEmptyOutletComponent} from './components/empty_outlet';
export {withPreloading as ɵwithPreloading} from './provide_router';
export {withLocationStrategy as ɵwithLocationStrategy, withPreloading as ɵwithPreloading} from './provide_router';
export {assignExtraOptionsToRouter as ɵassignExtraOptionsToRouter, RestoredState as ɵRestoredState} from './router';
export {ROUTER_PROVIDERS as ɵROUTER_PROVIDERS} from './router_module';
export {flatten as ɵflatten} from './utils/collection';
53 changes: 43 additions & 10 deletions packages/router/src/provide_router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@
* found in the LICENSE file at https://angular.io/license
*/

import {LOCATION_INITIALIZED, ViewportScroller} from '@angular/common';
import {HashLocationStrategy, LOCATION_INITIALIZED, LocationStrategy, PathLocationStrategy, ViewportScroller} from '@angular/common';
import {APP_BOOTSTRAP_LISTENER, APP_INITIALIZER, ApplicationRef, ComponentRef, ENVIRONMENT_INITIALIZER, inject, InjectFlags, InjectionToken, Injector, Provider, Type} from '@angular/core';
import {of, Subject} from 'rxjs';
import {filter, map, take} from 'rxjs/operators';

import {Event, NavigationCancel, NavigationCancellationCode, NavigationEnd, NavigationError, stringifyEvent} from './events';
import {Routes} from './models';
import {Router} from './router';
import {InMemoryScrollingOptions, ROUTER_CONFIGURATION, RouterConfigOptions} from './router_config';
import {InMemoryScrollingOptions, LocationStrategyOptions, ROUTER_CONFIGURATION, RouterConfigOptions} from './router_config';
import {ROUTES} from './router_config_loader';
import {provideHashLocationStrategy, providePathLocationStrategy} from './router_module';
import {PreloadingStrategy, RouterPreloader} from './router_preloader';
import {ROUTER_SCROLLER, RouterScroller} from './router_scroller';
import {ActivatedRoute} from './router_state';
Expand Down Expand Up @@ -110,9 +111,7 @@ function routerFeature<FeatureKind extends RouterFeatureKind>(
* @publicApi
*/
export function provideRoutes(routes: Routes): Provider[] {
return [
{provide: ROUTES, multi: true, useValue: routes},
];
return [{provide: ROUTES, multi: true, useValue: routes}];
}

/**
Expand Down Expand Up @@ -478,6 +477,39 @@ export function withDebugTracing(): DebugTracingFeature {
return routerFeature(RouterFeatureKind.DebugTracingFeature, providers);
}

/**
* Indicates whether Hash or Path strategy should be used
*
* @usageNotes
*
* Basic example of how you can enable location strategy;
* ```
* const appRoutes: Routes = [];
* bootstrapApplication(AppComponent,
* {
* providers: [
* provideRouter(appRoutes, withLocationStrategy({useHash: true}))
* ]
* }
* );
* ```
*
* @see `provideRouter`
*
* @returns A set of providers for use with `provideRouter`.
*
* @publicApi
* @developerPreview
*/
export function withLocationStrategy(options: LocationStrategyOptions):
RouterLocationStrategyFeature {
let providers: Provider[] = [];
options.useHash ? providers.push(provideHashLocationStrategy()) :
providers.push(providePathLocationStrategy());

return routerFeature(RouterFeatureKind.RouterLocationStrategyFeature, providers);
}

const ROUTER_PRELOADER = new InjectionToken<RouterPreloader>(NG_DEV_MODE ? 'router preloader' : '');

/**
Expand Down Expand Up @@ -539,6 +571,8 @@ export function withPreloading(preloadingStrategy: Type<PreloadingStrategy>): Pr
export type RouterConfigurationFeature =
RouterFeature<RouterFeatureKind.RouterConfigurationFeature>;

export type RouterLocationStrategyFeature =
RouterFeature<RouterFeatureKind.RouterLocationStrategyFeature>;
/**
* Allows to provide extra parameters to configure Router.
*
Expand Down Expand Up @@ -568,9 +602,7 @@ export type RouterConfigurationFeature =
* @developerPreview
*/
export function withRouterConfig(options: RouterConfigOptions): RouterConfigurationFeature {
const providers = [
{provide: ROUTER_CONFIGURATION, useValue: options},
];
const providers = [{provide: ROUTER_CONFIGURATION, useValue: options}];
return routerFeature(RouterFeatureKind.RouterConfigurationFeature, providers);
}

Expand All @@ -586,7 +618,7 @@ export function withRouterConfig(options: RouterConfigOptions): RouterConfigurat
* @developerPreview
*/
export type RouterFeatures = PreloadingFeature|DebugTracingFeature|InitialNavigationFeature|
InMemoryScrollingFeature|RouterConfigurationFeature;
InMemoryScrollingFeature|RouterConfigurationFeature|RouterLocationStrategyFeature;

/**
* The list of features as an enum to uniquely type each feature.
Expand All @@ -597,5 +629,6 @@ export const enum RouterFeatureKind {
EnabledBlockingInitialNavigationFeature,
DisabledInitialNavigationFeature,
InMemoryScrollingFeature,
RouterConfigurationFeature
RouterConfigurationFeature,
RouterLocationStrategyFeature
}
8 changes: 8 additions & 0 deletions packages/router/src/router_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,14 @@ export interface InMemoryScrollingOptions {
scrollPositionRestoration?: 'disabled'|'enabled'|'top';
}

/**
* A set of configuration options for a location strategy,
* either enabling HashLocationStrategy or PathlocationStrategy
*/
export interface LocationStrategyOptions {
useHash: boolean;
}

/**
* A set of configuration options for a router module, provided in the
* `forRoot()` method.
Expand Down
4 changes: 2 additions & 2 deletions packages/router/src/router_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,13 @@ export function provideRouterScroller(): Provider {

// Note: For internal use only with `RouterModule`. Standalone setup via `provideRouter` should
// provide hash location directly via `{provide: LocationStrategy, useClass: HashLocationStrategy}`.
function provideHashLocationStrategy(): Provider {
export function provideHashLocationStrategy(): Provider {
return {provide: LocationStrategy, useClass: HashLocationStrategy};
}

// Note: For internal use only with `RouterModule`. Standalone setup via `provideRouter` does not
// need this at all because `PathLocationStrategy` is the default factory for `LocationStrategy`.
function providePathLocationStrategy(): Provider {
export function providePathLocationStrategy(): Provider {
return {provide: LocationStrategy, useClass: PathLocationStrategy};
}

Expand Down
17 changes: 16 additions & 1 deletion packages/router/test/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {concat, defer, EMPTY, from, Observable, Observer, of, Subscription} from
import {delay, filter, first, last, map, mapTo, takeWhile, tap} from 'rxjs/operators';

import {CanActivateChildFn, CanActivateFn, CanMatch, CanMatchFn, ResolveFn} from '../src/models';
import {withRouterConfig} from '../src/provide_router';
import {withLocationStrategy, withRouterConfig} from '../src/provide_router';
import {forEach, wrapIntoObservable} from '../src/utils/collection';
import {getLoadedRoutes} from '../src/utils/config';
import {provideRouterForTesting} from '../testing/src/provide_router_for_testing';
Expand Down Expand Up @@ -6985,6 +6985,21 @@ describe('Testing router options', () => {
expect(router.urlUpdateStrategy).toBe('eager');
});
});

describe('should use the appropriate location strategy', () => {
it('using hash location',
() => {fakeAsync(() => {
TestBed.configureTestingModule({
declarations: [RootCmp],
providers: [provideRouterForTesting([], withLocationStrategy({useHash: true}))]
});
const router: Router = TestBed.inject(Router);
const fixture = createRoot(router, RootCmp);
router.navigateByUrl('/someUrl');
advance(fixture);
expect(router.url).toBe('/#/someUrl');
})});
});
});

function expectEvents(events: Event[], pairs: any[]) {
Expand Down