From d39360723940c85cc5a9ec1e5e017cd043c70251 Mon Sep 17 00:00:00 2001 From: gcca Date: Sun, 10 Sep 2017 19:32:26 -0500 Subject: [PATCH] feat(uiSrefStatus): emit state/params in events --- src/directives/uiSrefStatus.ts | 17 ++++++--- test/uiSrefStatus/uiSrefStatus.spec.ts | 51 ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 test/uiSrefStatus/uiSrefStatus.spec.ts diff --git a/src/directives/uiSrefStatus.ts b/src/directives/uiSrefStatus.ts index 8079cd193..1d4142bb0 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, + active: left.active || right.active, + exact: left.exact || right.exact, entering: left.entering || right.entering, - exiting: left.exiting || right.exiting, + 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..2069cec26 --- /dev/null +++ b/test/uiSrefStatus/uiSrefStatus.spec.ts @@ -0,0 +1,51 @@ +import { Component, DebugElement } from '@angular/core'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; + +import { SrefStatus, UISrefStatus } from '../../src/directives/uiSrefStatus'; +import { UIRouterModule } from '../../src/uiRouterNgModule'; + +describe('uiSrefStatus', () => { + @Component({ + template: '', + }) + class TestComponent { + updated(event: SrefStatus) { + throw new Error('updated() method must be spied'); + } + } + + let component: TestComponent; + let de: DebugElement; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [TestComponent], + imports: [UIRouterModule.forRoot({ + states: [{ name: 'foo' }], + useHash: true, + })] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(TestComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + de = fixture.debugElement.query(By.directive(UISrefStatus)); + }); + + describe('when click on `foo` uiSref', () => { + beforeEach(async(() => { + spyOn(component, 'updated'); + de.triggerEventHandler('click', {}); + })); + + it('should emit a event with identifier equals to `foo`', () => { + expect(component.updated).toHaveBeenCalledWith(jasmine.objectContaining({ + identifier: 'foo', + })); + }); + }); +});