diff --git a/src/directives/uiSrefStatus.ts b/src/directives/uiSrefStatus.ts index 8079cd193..a5903996f 100644 --- a/src/directives/uiSrefStatus.ts +++ b/src/directives/uiSrefStatus.ts @@ -3,7 +3,7 @@ import { Directive, Output, EventEmitter, ContentChildren, QueryList } from '@angular/core'; import { UISref } from './uiSref'; import { - PathNode, Transition, TargetState, StateObject, anyTrueR, tail, unnestR, Predicate, UIRouterGlobals, Param, PathUtils + PathNode, Transition, TargetState, StateObject, anyTrueR, tail, unnestR, Predicate, UIRouterGlobals, Param, PathUtils, StateOrName } from '@uirouter/core'; import { Subscription } from 'rxjs/Subscription'; @@ -32,6 +32,8 @@ export interface SrefStatus { entering: boolean; /** A transition is exiting the sref's target state */ exiting: boolean; + /** The sref's target state identifier */ + identifier: StateOrName; } /** @internalapi */ @@ -39,7 +41,8 @@ const inactiveStatus: SrefStatus = { active: false, exact: false, entering: false, - exiting: false + exiting: false, + identifier: null, }; /** @@ -117,16 +120,18 @@ function getSrefStatus(event: TransEvt, srefTarget: TargetState): SrefStatus { exact: isExact(), entering: isStartEvent ? isEntering() : false, exiting: isStartEvent ? isExiting() : false, + identifier: srefTarget.identifier(), } as SrefStatus; } /** @internalapi */ function mergeSrefStatus(left: SrefStatus, right: SrefStatus) { return { - active: left.active || right.active, - exact: left.exact || right.exact, - entering: left.entering || right.entering, - exiting: left.exiting || right.exiting, + active: left.active || right.active, + exact: left.exact || right.exact, + entering: left.entering || right.entering, + exiting: left.exiting || right.exiting, + identifier: left.identifier || right.identifier, }; } @@ -152,7 +157,7 @@ function mergeSrefStatus(left: SrefStatus, right: SrefStatus) { * ``` * * The `uiSrefStatus` event is emitted whenever an enclosed `uiSref`'s status changes. - * The event emitted is of type [[SrefStatus]], and has boolean values for `active`, `exact`, `entering`, and `exiting`. + * The event emitted is of type [[SrefStatus]], and has boolean values for `active`, `exact`, `entering`, and `exiting`; also has a [[StateOrName]] `identifier`value. * * The values from this event can be captured and stored on a component (then applied, e.g., using ngClass). * diff --git a/test/uiSrefStatus/uiSrefStatus.spec.ts b/test/uiSrefStatus/uiSrefStatus.spec.ts new file mode 100644 index 000000000..d037a84db --- /dev/null +++ b/test/uiSrefStatus/uiSrefStatus.spec.ts @@ -0,0 +1,55 @@ +import { Component, DebugElement } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; + +import { UISref } from '../../src/directives/uiSref'; +import { SrefStatus } from '../../src/directives/uiSrefStatus'; +import { UIRouterModule } from '../../src/uiRouterNgModule'; + +import { Subject } from 'rxjs/Subject'; + +describe('uiSrefStatus', () => { + @Component({ + template: '' + }) + class TestComponent extends Subject { + updated(event: SrefStatus) { + this.next(event); + } + } + + let de: DebugElement; + let comp: TestComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [TestComponent], + imports: [UIRouterModule.forRoot({ + states: [{ name: 'foo' }], + useHash: true, + })] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TestComponent); + comp = fixture.componentInstance; + fixture.detectChanges(); + de = fixture.debugElement.query(By.directive(UISref)); + }); + + describe('when click on `foo` uiSref', () => { + beforeEach(() => { + fixture.detectChanges(); + }); + + it('should emit a event with identifier equals to `foo`', done => { + comp.subscribe(event => { + expect(event.identifier).toEqual('foo'); + done(); + }); + de.triggerEventHandler('click', {}); + }); + }); +});