Skip to content

Commit 9ecc6e2

Browse files
jonrimmerchristopherthielen
authored andcommitted
fix(uiSref): run update when input properties change (#141)
1 parent b88401c commit 9ecc6e2

File tree

2 files changed

+95
-5
lines changed

2 files changed

+95
-5
lines changed

src/directives/uiSref.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** @ng2api @module directives */
22
/** */
33
import { UIRouter, extend, Obj, TransitionOptions, TargetState } from "@uirouter/core";
4-
import { Directive, Inject, Input, Optional, ElementRef, Renderer2 } from "@angular/core";
4+
import { Directive, Inject, Input, Optional, ElementRef, Renderer2, OnChanges, SimpleChanges } from "@angular/core";
55
import { UIView, ParentUIViewInject } from "./uiView";
66
import { ReplaySubject } from "rxjs/ReplaySubject";
77
import { Subscription } from "rxjs/Subscription";
@@ -70,7 +70,8 @@ export class AnchorUISref {
7070
selector: '[uiSref]',
7171
host: { '(click)': 'go()' }
7272
})
73-
export class UISref {
73+
export class UISref implements OnChanges {
74+
7475
/**
7576
* `@Input('uiSref')` The name of the state to link to
7677
*
@@ -134,6 +135,10 @@ export class UISref {
134135
this.update();
135136
}
136137

138+
ngOnChanges(changes: SimpleChanges): void {
139+
this.update();
140+
}
141+
137142
ngOnDestroy() {
138143
this._emit = false;
139144
this._statesSub.unsubscribe();

test/uiSref/uiSref.spec.ts

Lines changed: 88 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,41 @@
1-
import { Component, DebugElement } from '@angular/core';
1+
import { Component, DebugElement, ViewChildren, QueryList } from '@angular/core';
22
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
33
import { By } from '@angular/platform-browser';
44

55
import { UIRouterModule } from '../../src/uiRouterNgModule';
66
import { UISref } from '../../src/directives/uiSref';
7-
import { UIRouter } from '@uirouter/core';
7+
import { UIRouter, TargetState, TransitionOptions } from '@uirouter/core';
88
import { Subject } from 'rxjs/Subject';
9+
import { Subscription } from "rxjs/Subscription";
910

1011
describe('uiSref', () => {
1112
@Component({
1213
template: `
13-
<a [uiSref]="linkA" [target]="targetA"></a>
14+
<a [uiSref]="linkA" [target]="targetA" [uiParams]="linkAParams" [uiOptions]="linkAOptions"></a>
1415
<a [uiSref]="linkB"></a>
1516
`
1617
})
1718
class TestComponent {
1819
linkA: string;
20+
linkAParams: any;
21+
linkAOptions: TransitionOptions;
1922
targetA: string;
2023
linkB: string;
2124

25+
@ViewChildren(UISref) srefs: QueryList<UISref>;
26+
27+
get linkASref() {
28+
return this.srefs.first;
29+
}
30+
31+
get linkBSref() {
32+
return this.srefs.toArray()[1];
33+
}
34+
2235
constructor() {
2336
this.linkA = null;
37+
this.linkAParams = null;
38+
this.linkAOptions = null;
2439
this.targetA = '';
2540
this.linkB = '';
2641
}
@@ -40,6 +55,7 @@ describe('uiSref', () => {
4055
des = fixture.debugElement.queryAll(By.directive(UISref));
4156
});
4257

58+
4359
it('should not bind "null" string to `href`', () => {
4460
expect(des[0].nativeElement.hasAttribute('href')).toBeFalsy();
4561
expect(des[1].nativeElement.hasAttribute('href')).toBeFalsy();
@@ -114,6 +130,75 @@ describe('uiSref', () => {
114130
});
115131
});
116132
});
133+
134+
describe('when the bound values change', () => {
135+
let fixture: ComponentFixture<TestComponent>;
136+
let comp: TestComponent;
137+
let logger: TargetState[];
138+
let subscription: Subscription;
139+
140+
beforeEach(() => {
141+
fixture = TestBed.configureTestingModule({
142+
declarations: [TestComponent],
143+
imports: [UIRouterModule.forRoot({ useHash: true })]
144+
}).createComponent(TestComponent);
145+
fixture.detectChanges();
146+
comp = fixture.componentInstance;
147+
logger = [];
148+
subscription = comp.linkASref.targetState$.subscribe(evt => logger.push(evt));
149+
});
150+
151+
afterEach(() => {
152+
subscription.unsubscribe();
153+
});
154+
155+
describe('when the uiSref is empty', () => {
156+
it('should emit an empty target state event', () =>{
157+
expect(logger.length).toBe(1);
158+
expect(logger[0].name()).toBeNull();
159+
});
160+
})
161+
162+
describe('when the target state changes', () => {
163+
beforeEach(() => {
164+
comp.linkA = 'stateA';
165+
fixture.detectChanges();
166+
});
167+
168+
it('should emit an event', () => {
169+
expect(logger.length).toBe(2);
170+
expect(logger[1].name()).toBe('stateA');
171+
});
172+
});
173+
174+
describe('when the target params change', () => {
175+
const params = { paramA: 'paramA' };
176+
177+
beforeEach(() => {
178+
comp.linkAParams = params;
179+
fixture.detectChanges();
180+
});
181+
182+
it('should emit an event', () => {
183+
expect(logger.length).toBe(2);
184+
expect(logger[1].params()).toEqual(params);
185+
});
186+
});
187+
188+
describe('when the transition options change', () => {
189+
const options: TransitionOptions = { custom: 'custom' };
190+
191+
beforeEach(() => {
192+
comp.linkAOptions = options;
193+
fixture.detectChanges();
194+
});
195+
196+
it ('should emit an event', () => {
197+
expect(logger.length).toBe(2);
198+
expect(logger[1].options().custom).toEqual(options.custom);
199+
});
200+
})
201+
});
117202
});
118203
});
119204

0 commit comments

Comments
 (0)