feat(aio): add location service
This commit is contained in:
parent
3883b736c0
commit
887d32a9bf
|
@ -0,0 +1,122 @@
|
|||
import { ReflectiveInjector } from '@angular/core';
|
||||
import { Location, LocationStrategy } from '@angular/common';
|
||||
import { MockLocationStrategy } from '@angular/common/testing';
|
||||
import { LocationService } from './location.service';
|
||||
|
||||
fdescribe('LocationService', () => {
|
||||
|
||||
let injector: ReflectiveInjector;
|
||||
|
||||
beforeEach(() => {
|
||||
injector = ReflectiveInjector.resolveAndCreate([
|
||||
LocationService,
|
||||
Location,
|
||||
{ provide: LocationStrategy, useClass: MockLocationStrategy }
|
||||
]);
|
||||
});
|
||||
|
||||
describe('urlStream', () => {
|
||||
it('should emit the latest url at the time it is subscribed to', () => {
|
||||
|
||||
const location: MockLocationStrategy = injector.get(LocationStrategy);
|
||||
|
||||
location.simulatePopState('/initial-url1');
|
||||
location.simulatePopState('/initial-url2');
|
||||
location.simulatePopState('/initial-url3');
|
||||
|
||||
const service: LocationService = injector.get(LocationService);
|
||||
|
||||
location.simulatePopState('/next-url1');
|
||||
location.simulatePopState('/next-url2');
|
||||
location.simulatePopState('/next-url3');
|
||||
|
||||
let initialUrl;
|
||||
service.currentUrl.subscribe(url => initialUrl = url);
|
||||
expect(initialUrl).toEqual('/next-url3');
|
||||
});
|
||||
|
||||
it('should emit all location changes after it has been subscribed to', () => {
|
||||
const location: MockLocationStrategy = injector.get(LocationStrategy);
|
||||
const service: LocationService = injector.get(LocationService);
|
||||
|
||||
location.simulatePopState('/initial-url1');
|
||||
location.simulatePopState('/initial-url2');
|
||||
location.simulatePopState('/initial-url3');
|
||||
|
||||
const urls = [];
|
||||
service.currentUrl.subscribe(url => urls.push(url));
|
||||
|
||||
location.simulatePopState('/next-url1');
|
||||
location.simulatePopState('/next-url2');
|
||||
location.simulatePopState('/next-url3');
|
||||
|
||||
expect(urls).toEqual([
|
||||
'/initial-url3',
|
||||
'/next-url1',
|
||||
'/next-url2',
|
||||
'/next-url3'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should pass only the latest and later urls to each subscriber', () => {
|
||||
const location: MockLocationStrategy = injector.get(LocationStrategy);
|
||||
const service: LocationService = injector.get(LocationService);
|
||||
|
||||
location.simulatePopState('/initial-url1');
|
||||
location.simulatePopState('/initial-url2');
|
||||
location.simulatePopState('/initial-url3');
|
||||
|
||||
const urls1 = [];
|
||||
service.currentUrl.subscribe(url => urls1.push(url));
|
||||
|
||||
location.simulatePopState('/next-url1');
|
||||
location.simulatePopState('/next-url2');
|
||||
|
||||
const urls2 = [];
|
||||
service.currentUrl.subscribe(url => urls2.push(url));
|
||||
|
||||
location.simulatePopState('/next-url3');
|
||||
|
||||
expect(urls1).toEqual([
|
||||
'/initial-url3',
|
||||
'/next-url1',
|
||||
'/next-url2',
|
||||
'/next-url3'
|
||||
]);
|
||||
|
||||
expect(urls2).toEqual([
|
||||
'/next-url2',
|
||||
'/next-url3'
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('go', () => {
|
||||
it('should update the location', () => {
|
||||
const location: MockLocationStrategy = injector.get(LocationStrategy);
|
||||
const service: LocationService = injector.get(LocationService);
|
||||
|
||||
service.go('some-new-url');
|
||||
|
||||
expect(location.internalPath).toEqual('some-new-url');
|
||||
expect(location.path(true)).toEqual('some-new-url');
|
||||
});
|
||||
|
||||
it('should emit the new url', () => {
|
||||
const location: MockLocationStrategy = injector.get(LocationStrategy);
|
||||
const service: LocationService = injector.get(LocationService);
|
||||
|
||||
service.go('some-initial-url');
|
||||
|
||||
const urls = [];
|
||||
service.currentUrl.subscribe(url => urls.push(url));
|
||||
|
||||
service.go('some-new-url');
|
||||
|
||||
expect(urls).toEqual([
|
||||
'some-initial-url',
|
||||
'some-new-url'
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
|
||||
@Injectable()
|
||||
export class LocationService {
|
||||
|
||||
private urlSubject: BehaviorSubject<string>;
|
||||
get currentUrl() { return this.urlSubject.asObservable(); }
|
||||
|
||||
constructor(private location: Location) {
|
||||
this.urlSubject = new BehaviorSubject(location.path(true));
|
||||
this.location.subscribe(state => this.urlSubject.next(state.url));
|
||||
}
|
||||
|
||||
go(url: string) {
|
||||
url = this.location.normalize(url);
|
||||
this.location.go(url);
|
||||
this.urlSubject.next(url);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue