Skip to content

Commit 025ebc8

Browse files
fix(ui-state): update ui-sref-active/eq info
Closes #2488
1 parent e441a7c commit 025ebc8

File tree

2 files changed

+52
-7
lines changed

2 files changed

+52
-7
lines changed

src/ng1/stateDirectives.ts

+16-4
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,17 @@ function $StateRefDynamicDirective($state, $timeout) {
179179
var group = [attrs.uiState, attrs.uiStateParams || null, attrs.uiStateOpts || null];
180180
var watch = '[' + group.map(function(val) { return val || 'null'; }).join(', ') + ']';
181181
var def = { state: null, params: null, options: null, href: null };
182+
var unlinkInfoFn = null;
182183

183184
function runStateRefLink (group) {
184185
def.state = group[0]; def.params = group[1]; def.options = group[2];
185186
def.href = $state.href(def.state, def.params, def.options);
186187

187-
if (active) active.$$addStateInfo(def.state, def.params);
188+
if (unlinkInfoFn) {
189+
unlinkInfoFn();
190+
unlinkInfoFn = null;
191+
}
192+
if (active) unlinkInfoFn = active.$$addStateInfo(def.state, def.params);
188193
if (def.href) attrs.$set(type.attr, def.href);
189194
}
190195

@@ -325,8 +330,9 @@ function $StateRefActiveDirective($state, $stateParams, $interpolate, $transitio
325330
if (isObject(uiSrefActive) && states.length > 0) {
326331
return;
327332
}
328-
addState(newState, newParams, uiSrefActive);
333+
var deregister = addState(newState, newParams, uiSrefActive);
329334
update();
335+
return deregister;
330336
};
331337

332338
$scope.$on('$stateChangeSuccess', update);
@@ -338,13 +344,19 @@ function $StateRefActiveDirective($state, $stateParams, $interpolate, $transitio
338344
var state = $state.get(stateName, stateContext($element));
339345
var stateHash = createStateHash(stateName, stateParams);
340346

341-
states.push({
347+
var stateInfo = {
342348
state: state || { name: stateName },
343349
params: stateParams,
344350
hash: stateHash
345-
});
351+
};
346352

353+
states.push(stateInfo);
347354
activeClasses[stateHash] = activeClass;
355+
356+
return function removeState() {
357+
var idx = states.indexOf(stateInfo);
358+
if (idx !== -1) states.splice(idx, 1);
359+
}
348360
}
349361

350362
/**

test/stateDirectivesSpec.js

+36-3
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,11 @@ describe('uiStateRef', function() {
302302
});
303303

304304
describe('links with dynamic state definitions', function () {
305-
var template;
305+
var template, $state;
306306

307-
beforeEach(inject(function($rootScope, $compile, $state) {
308-
el = angular.element('<a ui-state="state" ui-state-params="params">state</a>');
307+
beforeEach(inject(function($rootScope, $compile, _$state_) {
308+
$state = _$state_;
309+
el = angular.element('<a ui-sref-active="active" ui-sref-active-eq="activeeq" ui-state="state" ui-state-params="params">state</a>');
309310
scope = $rootScope;
310311
angular.extend(scope, { state: 'contacts', params: {} });
311312
template = $compile(el)(scope);
@@ -329,6 +330,38 @@ describe('uiStateRef', function() {
329330
expect(angular.element(template[0]).attr('href')).toBe('#/contacts/25');
330331
});
331332

333+
it('updates a linked ui-sref-active', inject(function ($timeout) {
334+
function tick() { scope.$digest(); try { $timeout.flush(); } catch (error) { } }
335+
expect(template[0].className).not.toContain('active');
336+
expect(template[0].className).not.toContain('activeeq');
337+
338+
$state.go('contacts');
339+
tick();
340+
expect(template[0].className).toContain('active activeeq');
341+
342+
scope.state = 'contacts.item';
343+
scope.params = { id: 5 };
344+
tick();
345+
expect(template[0].className).not.toContain('active');
346+
expect(template[0].className).not.toContain('activeeq');
347+
348+
$state.go('contacts.item', { id: -5 });
349+
tick();
350+
expect(template[0].className).not.toContain('active');
351+
expect(template[0].className).not.toContain('activeeq');
352+
353+
$state.go('contacts.item', { id: 5 });
354+
tick();
355+
expect(template[0].className).toContain('active activeeq');
356+
357+
scope.state = 'contacts';
358+
scope.params = { };
359+
tick();
360+
expect(template[0].className).toContain('active');
361+
expect(template[0].className).not.toContain('activeeq');
362+
363+
}));
364+
332365
it('retains the old href if the new points to a non-state', function () {
333366
expect(angular.element(template[0]).attr('href')).toBe('#/contacts');
334367
scope.state = 'nostate';

0 commit comments

Comments
 (0)