diff --git a/CHANGELOG.md b/CHANGELOG.md index dc0fdb5..b6b3a83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 1.8.0 (2020-08-10) + +## New feature + +- Allow to change navigation prefix at runtime [ebrehault] + # 1.7.1 (2020-07-24) ## Improvement diff --git a/README.md b/README.md index a719222..bf76e91 100644 --- a/README.md +++ b/README.md @@ -373,7 +373,7 @@ Note: with `noAutoTraverse`, we will not traverse to the new location everytime In our app module, we will declare our prefix: ```typescript -{ provide: NAVIGATION_PREFIX, useValue: '/files' }, +{ provide: NAVIGATION_PREFIX, useValue: new BehaviorSubject('/files') }, ``` And in order to make sure the transition between the 2 modes work fine, we will have to do (in app.component for example): diff --git a/projects/traversal/package.json b/projects/traversal/package.json index de42088..2eaf4d1 100644 --- a/projects/traversal/package.json +++ b/projects/traversal/package.json @@ -1,6 +1,6 @@ { "name": "angular-traversal", - "version": "1.7.1", + "version": "1.8.0", "license": "MIT", "author": { "name": "Eric Brehault", diff --git a/projects/traversal/src/lib/traverser.directive.ts b/projects/traversal/src/lib/traverser.directive.ts index 614763a..9dece5e 100644 --- a/projects/traversal/src/lib/traverser.directive.ts +++ b/projects/traversal/src/lib/traverser.directive.ts @@ -13,31 +13,27 @@ import { Location } from '@angular/common'; import { Traverser, NAVIGATION_PREFIX } from './traverser'; import { Target } from './interfaces'; import { takeUntil } from 'rxjs/operators'; -import { Subject } from 'rxjs'; +import { Subject, BehaviorSubject } from 'rxjs'; @Directive({ selector: 'traverser-outlet', }) export class TraverserOutlet implements OnInit, OnDestroy { private viewInstance: any; - private prefix: string; private terminator: Subject = new Subject(); constructor( private traverser: Traverser, private location: Location, private container: ViewContainerRef, - @Optional() @Inject(NAVIGATION_PREFIX) prefix: string, private cdr: ChangeDetectorRef - ) { - this.prefix = prefix || ''; - } + ) {} ngOnInit() { this.traverser.target.pipe(takeUntil(this.terminator)).subscribe((target: Target) => this.render(target)); - this.traverser.traverse(this.location.path().slice(this.prefix.length), false); + this.traverser.traverse(this.location.path().replace('/' + this.traverser.getPrefix(), ''), false); this.location.subscribe((loc) => { - const path = (loc.url || '').slice(this.prefix.length); + const path = (loc.url || '').replace('/' + this.traverser.getPrefix(), ''); this.traverser.traverse(path || '/', false); // when empty string traverse to root }); } diff --git a/projects/traversal/src/lib/traverser.link.ts b/projects/traversal/src/lib/traverser.link.ts index ee85b3b..772655d 100644 --- a/projects/traversal/src/lib/traverser.link.ts +++ b/projects/traversal/src/lib/traverser.link.ts @@ -1,5 +1,5 @@ -import { Directive, HostBinding, Input, OnInit, Optional, Inject, HostListener } from '@angular/core'; -import { Traverser, NAVIGATION_PREFIX } from './traverser'; +import { Directive, HostBinding, Input, OnInit, HostListener } from '@angular/core'; +import { Traverser } from './traverser'; import { Normalizer } from './normalizer'; @Directive({ @@ -24,20 +24,16 @@ export class TraverserButton { }) export class TraverserLink extends TraverserButton implements OnInit { @HostBinding() href?: string; - private prefix: string; - constructor( - private privateTraverser: Traverser, - private normalizer: Normalizer, - @Optional() @Inject(NAVIGATION_PREFIX) prefix: string - ) { + constructor(private privateTraverser: Traverser, private normalizer: Normalizer) { super(privateTraverser); - this.prefix = prefix || ''; } ngOnInit() { if (!!this.traverseTo) { - this.href = this.prefix + this.normalizer.normalize(this.privateTraverser.getFullPath(this.traverseTo)); + this.href = + this.privateTraverser.getPrefix() + + this.normalizer.normalize(this.privateTraverser.getFullPath(this.traverseTo)); } } } diff --git a/projects/traversal/src/lib/traverser.ts b/projects/traversal/src/lib/traverser.ts index e39ea06..2aa3edb 100644 --- a/projects/traversal/src/lib/traverser.ts +++ b/projects/traversal/src/lib/traverser.ts @@ -11,7 +11,7 @@ import { } from '@angular/core'; import { Location } from '@angular/common'; import { HttpParams } from '@angular/common/http'; -import { BehaviorSubject, of, Observable, Subject, combineLatest } from 'rxjs'; +import { BehaviorSubject, of, Observable, Subject } from 'rxjs'; import { take, withLatestFrom, map } from 'rxjs/operators'; import { Resolver } from './resolver'; import { Marker } from './marker'; @@ -20,7 +20,7 @@ import { Target, HttpParamsOptions, ModuleWithViews, ViewMapping } from './inter export type LazyView = () => Promise>; -export const NAVIGATION_PREFIX = new InjectionToken('traversal.prefix'); +export const NAVIGATION_PREFIX = new InjectionToken>('traversal.prefix'); @Injectable({ providedIn: 'root', @@ -37,7 +37,6 @@ export class Traverser { private lazy: { [id: string]: LazyView } = {}; private lazyModules: { [id: string]: boolean } = {}; private tiles: { [name: string]: { [target: string]: any } } = {}; - private prefix: string; constructor( private location: Location, @@ -47,9 +46,8 @@ export class Traverser { private ngResolver: ComponentFactoryResolver, private compiler: Compiler, private injector: Injector, - @Optional() @Inject(NAVIGATION_PREFIX) prefix: string + @Optional() @Inject(NAVIGATION_PREFIX) private prefix: BehaviorSubject ) { - this.prefix = prefix || ''; this.target = new BehaviorSubject(this.getEmptyTarget()); let answers: boolean[] = []; this.echo.subscribe((ok) => { @@ -104,8 +102,8 @@ export class Traverser { } navigateTo = this.target.value.contextPath + navigateTo; } - if (this.location.path() !== this.prefix + navigateTo) { - this.location.go(this.prefix + navigateTo); + if (this.location.path() !== this.getPrefix() + navigateTo) { + this.location.go(this.getPrefix() + navigateTo); } } let components = this.views[view]; @@ -119,7 +117,7 @@ export class Traverser { } traverseHere(includeHash = true) { - const here = this.location.path().slice(this.prefix.length); + const here = this.location.path().replace('/' + this.getPrefix(), ''); this.traverse(!includeHash ? here.split('?')[0] : here); } @@ -249,9 +247,9 @@ export class Traverser { ? ({ context, path, - prefixedPath: this.prefix + path, + prefixedPath: this.getPrefix() + path, contextPath, - prefixedContextPath: this.prefix + contextPath, + prefixedContextPath: this.getPrefix() + contextPath, view: viewOrTile, component: comp, query: new HttpParams({ fromString: queryString || '' } as HttpParamsOptions), @@ -317,9 +315,9 @@ export class Traverser { component: null, context: {}, contextPath: '', - prefixedContextPath: this.prefix, + prefixedContextPath: this.getPrefix(), path: '', - prefixedPath: this.prefix, + prefixedPath: this.getPrefix(), query: new HttpParams(), view: 'view', }; @@ -344,4 +342,12 @@ export class Traverser { }) ); } + + getPrefix(): string { + return !!this.prefix ? this.prefix.getValue() : ''; + } + + setPrefix(prefix: string) { + this.prefix.next(prefix); + } }