Skip to content

Commit

Permalink
feat(uiSrefActive): Added support for multiple nested uiSref directives
Browse files Browse the repository at this point in the history
  • Loading branch information
sbezkostnyi committed Apr 7, 2015
1 parent 0250291 commit b184494
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 10 deletions.
34 changes: 24 additions & 10 deletions src/stateDirectives.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ function $StateRefDirective($state, $timeout) {

var activeDirective = uiSrefActive[1] || uiSrefActive[0];
if (activeDirective) {
activeDirective.$$setStateInfo(ref.state, params);
activeDirective.$$addStateInfo(ref.state, params);
}
if (newHref === null) {
nav = false;
Expand Down Expand Up @@ -229,36 +229,50 @@ function $StateRefActiveDirective($state, $stateParams, $interpolate) {
return {
restrict: "A",
controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
var state, params, activeClass;
var states = [], activeClass;

// There probably isn't much point in $observing this
// uiSrefActive and uiSrefActiveEq share the same directive object with some
// slight difference in logic routing
activeClass = $interpolate($attrs.uiSrefActiveEq || $attrs.uiSrefActive || '', false)($scope);

// Allow uiSref to communicate with uiSrefActive[Equals]
this.$$setStateInfo = function (newState, newParams) {
state = $state.get(newState, stateContext($element));
params = newParams;
update();
this.$$addStateInfo = function (newState, newParams) {
var state = $state.get(newState, stateContext($element));
if (state) {
states.push({
state: state,
params: newParams
});
update();
}
};

$scope.$on('$stateChangeSuccess', update);

// Update route state
function update() {
if (isMatch()) {
if (anyMatch()) {
$element.addClass(activeClass);
} else {
$element.removeClass(activeClass);
}
}

function isMatch() {
function anyMatch() {
for (var i = 0; i < states.length; i++) {
if (isMatch(states[i].state, states[i].params)) {
return true;
}
}
return false;
}

function isMatch(state, params) {
if (typeof $attrs.uiSrefActiveEq !== 'undefined') {
return state && $state.is(state.name, params);
return $state.is(state.name, params);
} else {
return state && $state.includes(state.name, params);
return $state.includes(state.name, params);
}
}
}]
Expand Down
16 changes: 16 additions & 0 deletions test/stateDirectivesSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,22 @@ describe('uiSrefActive', function() {
$q.flush();
expect(angular.element(template[0].querySelector('a')).attr('class')).toBe('ng-scope');
}));

it('should match on any child state refs', inject(function($rootScope, $q, $compile, $state) {
el = angular.element('<div ui-sref-active="active"><a ui-sref="contacts.item({ id: 1 })">Contacts</a><a ui-sref="contacts.item({ id: 2 })">Contacts</a></div>');
template = $compile(el)($rootScope);
$rootScope.$digest();

expect(angular.element(template[0]).attr('class')).toBe('ng-scope');

$state.transitionTo('contacts.item', { id: 1 });
$q.flush();
expect(angular.element(template[0]).attr('class')).toBe('ng-scope active');

$state.transitionTo('contacts.item', { id: 2 });
$q.flush();
expect(angular.element(template[0]).attr('class')).toBe('ng-scope active');
}));
});

describe('uiView controllers or onEnter handlers', function() {
Expand Down

0 comments on commit b184494

Please sign in to comment.