diff --git a/src/directives/uiSref.ts b/src/directives/uiSref.ts index 8825b826f..598f3ad93 100644 --- a/src/directives/uiSref.ts +++ b/src/directives/uiSref.ts @@ -1,7 +1,7 @@ /** @ng2api @module directives */ /** */ import { UIRouter, extend, Obj, TransitionOptions, TargetState } from "@uirouter/core"; -import { Directive, Inject, Input, Optional, ElementRef, Renderer2 } from "@angular/core"; +import { Directive, Inject, Input, Optional, ElementRef, Renderer2, OnChanges, SimpleChanges } from "@angular/core"; import { UIView, ParentUIViewInject } from "./uiView"; import { ReplaySubject } from "rxjs/ReplaySubject"; import { Subscription } from "rxjs/Subscription"; @@ -70,7 +70,8 @@ export class AnchorUISref { selector: '[uiSref]', host: { '(click)': 'go()' } }) -export class UISref { +export class UISref implements OnChanges { + /** * `@Input('uiSref')` The name of the state to link to * @@ -134,6 +135,10 @@ export class UISref { this.update(); } + ngOnChanges(changes: SimpleChanges): void { + this.update(); + } + ngOnDestroy() { this._emit = false; this._statesSub.unsubscribe(); diff --git a/test/uiSref/uiSref.spec.ts b/test/uiSref/uiSref.spec.ts index 2dde88b73..4ec09cec5 100644 --- a/test/uiSref/uiSref.spec.ts +++ b/test/uiSref/uiSref.spec.ts @@ -1,26 +1,41 @@ -import { Component, DebugElement } from '@angular/core'; +import { Component, DebugElement, ViewChildren, QueryList } from '@angular/core'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { UIRouterModule } from '../../src/uiRouterNgModule'; import { UISref } from '../../src/directives/uiSref'; -import { UIRouter } from '@uirouter/core'; +import { UIRouter, TargetState, TransitionOptions } from '@uirouter/core'; import { Subject } from 'rxjs/Subject'; +import { Subscription } from "rxjs/Subscription"; describe('uiSref', () => { @Component({ template: ` - + ` }) class TestComponent { linkA: string; + linkAParams: any; + linkAOptions: TransitionOptions; targetA: string; linkB: string; + @ViewChildren(UISref) srefs: QueryList; + + get linkASref() { + return this.srefs.first; + } + + get linkBSref() { + return this.srefs.toArray()[1]; + } + constructor() { this.linkA = null; + this.linkAParams = null; + this.linkAOptions = null; this.targetA = ''; this.linkB = ''; } @@ -40,6 +55,7 @@ describe('uiSref', () => { des = fixture.debugElement.queryAll(By.directive(UISref)); }); + it('should not bind "null" string to `href`', () => { expect(des[0].nativeElement.hasAttribute('href')).toBeFalsy(); expect(des[1].nativeElement.hasAttribute('href')).toBeFalsy(); @@ -114,6 +130,75 @@ describe('uiSref', () => { }); }); }); + + describe('when the bound values change', () => { + let fixture: ComponentFixture; + let comp: TestComponent; + let logger: TargetState[]; + let subscription: Subscription; + + beforeEach(() => { + fixture = TestBed.configureTestingModule({ + declarations: [TestComponent], + imports: [UIRouterModule.forRoot({ useHash: true })] + }).createComponent(TestComponent); + fixture.detectChanges(); + comp = fixture.componentInstance; + logger = []; + subscription = comp.linkASref.targetState$.subscribe(evt => logger.push(evt)); + }); + + afterEach(() => { + subscription.unsubscribe(); + }); + + describe('when the uiSref is empty', () => { + it('should emit an empty target state event', () =>{ + expect(logger.length).toBe(1); + expect(logger[0].name()).toBeNull(); + }); + }) + + describe('when the target state changes', () => { + beforeEach(() => { + comp.linkA = 'stateA'; + fixture.detectChanges(); + }); + + it('should emit an event', () => { + expect(logger.length).toBe(2); + expect(logger[1].name()).toBe('stateA'); + }); + }); + + describe('when the target params change', () => { + const params = { paramA: 'paramA' }; + + beforeEach(() => { + comp.linkAParams = params; + fixture.detectChanges(); + }); + + it('should emit an event', () => { + expect(logger.length).toBe(2); + expect(logger[1].params()).toEqual(params); + }); + }); + + describe('when the transition options change', () => { + const options: TransitionOptions = { custom: 'custom' }; + + beforeEach(() => { + comp.linkAOptions = options; + fixture.detectChanges(); + }); + + it ('should emit an event', () => { + expect(logger.length).toBe(2); + expect(logger[1].options().custom).toEqual(options.custom); + }); + }) + }); }); });