feat(common): add ability to track all location changes (#30055)
This feature adds an `onUrlChange` to Angular's `Location` class. This is useful to track all updates coming from anywhere in the framework. Without this method, it's difficult (or impossible) to track updates run through `location.go()` or `location.replaceState()` as the browser doesn't publish events when `history.pushState()` or `.replaceState()` are run. PR Close #30055
This commit is contained in:
@ -6,18 +6,23 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Location, LocationStrategy} from '@angular/common';
|
||||
import {Location, LocationStrategy, PlatformLocation} from '@angular/common';
|
||||
import {EventEmitter, Injectable} from '@angular/core';
|
||||
import {SubscriptionLike} from 'rxjs';
|
||||
|
||||
|
||||
const urlChangeListeners: ((url: string, state: unknown) => void)[] = [];
|
||||
function notifyUrlChangeListeners(url: string = '', state: unknown) {
|
||||
urlChangeListeners.forEach(fn => fn(url, state));
|
||||
}
|
||||
|
||||
/**
|
||||
* A spy for {@link Location} that allows tests to fire simulated location events.
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
@Injectable()
|
||||
export class SpyLocation implements Location {
|
||||
export class SpyLocation extends Location {
|
||||
urlChanges: string[] = [];
|
||||
private _history: LocationState[] = [new LocationState('', '', null)];
|
||||
private _historyIndex: number = 0;
|
||||
@ -27,6 +32,8 @@ export class SpyLocation implements Location {
|
||||
_baseHref: string = '';
|
||||
/** @internal */
|
||||
_platformStrategy: LocationStrategy = null !;
|
||||
/** @internal */
|
||||
_platformLocation: PlatformLocation = null !;
|
||||
|
||||
setInitialPath(url: string) { this._history[this._historyIndex].path = url; }
|
||||
|
||||
@ -110,6 +117,10 @@ export class SpyLocation implements Location {
|
||||
this._subject.emit({'url': this.path(), 'state': this.getState(), 'pop': true});
|
||||
}
|
||||
}
|
||||
onUrlChange(fn: (url: string, state: unknown) => void) {
|
||||
urlChangeListeners.push(fn);
|
||||
this.subscribe(v => { notifyUrlChangeListeners(v.url, v.state); });
|
||||
}
|
||||
|
||||
subscribe(
|
||||
onNext: (value: any) => void, onThrow?: ((error: any) => void)|null,
|
||||
|
Reference in New Issue
Block a user