Skip to content

Commit

Permalink
fix(ui-state): update ui-sref-active/eq info
Browse files Browse the repository at this point in the history
when ui-state dynamicly changes watchers, make sure to update the ui-sref-active/eq
Closes #2488
  • Loading branch information
christopherthielen committed Feb 14, 2016
1 parent 83d6661 commit abb3deb
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 7 deletions.
20 changes: 16 additions & 4 deletions src/stateDirectives.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,17 @@ function $StateRefDynamicDirective($state, $timeout) {
var group = [attrs.uiState, attrs.uiStateParams || null, attrs.uiStateOpts || null];
var watch = '[' + group.map(function(val) { return val || 'null'; }).join(', ') + ']';
var def = { state: null, params: null, options: null, href: null };
var unlinkInfoFn = null;

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

if (active) active.$$addStateInfo(def.state, def.params);
if (unlinkInfoFn) {
unlinkInfoFn();
unlinkInfoFn = null;
}
if (active) unlinkInfoFn = active.$$addStateInfo(def.state, def.params);
if (def.href) attrs.$set(type.attr, def.href);
}

Expand Down Expand Up @@ -319,8 +324,9 @@ function $StateRefActiveDirective($state, $stateParams, $interpolate) {
if (isObject(uiSrefActive) && states.length > 0) {
return;
}
addState(newState, newParams, uiSrefActive);
var deregister = addState(newState, newParams, uiSrefActive);
update();
return deregister;
};

$scope.$on('$stateChangeSuccess', update);
Expand All @@ -329,13 +335,19 @@ function $StateRefActiveDirective($state, $stateParams, $interpolate) {
var state = $state.get(stateName, stateContext($element));
var stateHash = createStateHash(stateName, stateParams);

states.push({
var stateInfo = {
state: state || { name: stateName },
params: stateParams,
hash: stateHash
});
};

states.push(stateInfo);
activeClasses[stateHash] = activeClass;

return function removeState() {
var idx = states.indexOf(stateInfo);
if (idx !== -1) states.splice(idx, 1);
};
}

/**
Expand Down
39 changes: 36 additions & 3 deletions test/stateDirectivesSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,10 +292,11 @@ describe('uiStateRef', function() {
});

describe('links with dynamic state definitions', function () {
var template;
var template, $state;

beforeEach(inject(function($rootScope, $compile, $state) {
el = angular.element('<a ui-state="state" ui-state-params="params">state</a>');
beforeEach(inject(function($rootScope, $compile, _$state_) {
$state = _$state_;
el = angular.element('<a ui-sref-active="active" ui-sref-active-eq="activeeq" ui-state="state" ui-state-params="params">state</a>');
scope = $rootScope;
angular.extend(scope, { state: 'contacts', params: {} });
template = $compile(el)(scope);
Expand Down Expand Up @@ -326,6 +327,38 @@ describe('uiStateRef', function() {
expect(angular.element(template[0]).attr('href')).toBe('#/contacts');
});

it('updates a linked ui-sref-active', inject(function ($timeout) {
function tick() { scope.$digest(); try { $timeout.flush(); } catch (error) { } }
expect(template[0].className).not.toContain('active');
expect(template[0].className).not.toContain('activeeq');

$state.go('contacts');
tick();
expect(template[0].className).toContain('active activeeq');

scope.state = 'contacts.item';
scope.params = { id: 5 };
tick();
expect(template[0].className).not.toContain('active');
expect(template[0].className).not.toContain('activeeq');

$state.go('contacts.item', { id: -5 });
tick();
expect(template[0].className).not.toContain('active');
expect(template[0].className).not.toContain('activeeq');

$state.go('contacts.item', { id: 5 });
tick();
expect(template[0].className).toContain('active activeeq');

scope.state = 'contacts';
scope.params = { };
tick();
expect(template[0].className).toContain('active');
expect(template[0].className).not.toContain('activeeq');

}));

it('accepts param overrides', inject(function ($compile) {
el = angular.element('<a ui-state="state" ui-state-params="params">state</a>');
scope.state = 'contacts.item';
Expand Down

0 comments on commit abb3deb

Please sign in to comment.