Skip to content

Commit

Permalink
fix(uiView): Fixed infinite loop when is called .go() from a controll…
Browse files Browse the repository at this point in the history
…er. Closes #1194
  • Loading branch information
christopherthielen committed Aug 27, 2014
1 parent b92211d commit e13988b
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 12 deletions.
24 changes: 12 additions & 12 deletions src/viewDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,11 @@ function $ViewDirective( $state, $injector, $uiViewScroll) {

function updateView(firstTime) {
var newScope = scope.$new(),
name = currentEl && currentEl.data('$uiViewName'),
name = getUiViewName(attrs, $element.inheritedData('$uiView')),
previousLocals = name && $state.$current && $state.$current.locals[name];

if (!firstTime && previousLocals === latestLocals) return; // nothing to do
latestLocals = $state.$current.locals[name];

var clone = $transclude(newScope, function(clone) {
renderer.enter(clone, $element, function onUiViewEnter() {
Expand All @@ -217,8 +218,6 @@ function $ViewDirective( $state, $injector, $uiViewScroll) {
cleanupLastView();
});

latestLocals = $state.$current.locals[clone.data('$uiViewName')];

currentEl = clone;
currentScope = newScope;
/**
Expand Down Expand Up @@ -249,16 +248,8 @@ function $ViewDirectiveFill ($compile, $controller, $state) {
compile: function (tElement) {
var initial = tElement.html();
return function (scope, $element, attrs) {
var name = attrs.uiView || attrs.name || '',
inherited = $element.inheritedData('$uiView');

if (name.indexOf('@') < 0) {
name = name + '@' + (inherited ? inherited.state.name : '');
}

$element.data('$uiViewName', name);

var current = $state.$current,
name = getUiViewName(attrs, $element.inheritedData('$uiView')),
locals = current && current.locals[name];

if (! locals) {
Expand Down Expand Up @@ -286,5 +277,14 @@ function $ViewDirectiveFill ($compile, $controller, $state) {
};
}

/**
* Shared ui-view code for both directives:
* Given attributes and inherited $uiView data, return the view's name
*/
function getUiViewName(attrs, inherited) {
var name = attrs.uiView || attrs.name || '';
return name.indexOf('@') >= 0 ? name : (name + '@' + (inherited ? inherited.state.name : ''));
}

angular.module('ui.router.state').directive('uiView', $ViewDirective);
angular.module('ui.router.state').directive('uiView', $ViewDirectiveFill);
47 changes: 47 additions & 0 deletions test/stateDirectivesSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,3 +447,50 @@ describe('uiSrefActive', function() {
expect(angular.element(template[0].querySelector('a')).attr('class')).toBe('ng-scope');
}));
});

describe('uiView controllers or onEnter handlers', function() {
var el, template, scope, document, count;

beforeEach(module('ui.router'));

beforeEach(module(function($stateProvider) {
count = 0;
$stateProvider
.state('aside', { url: '/aside', template: '<div class="aside"></div>' })
.state('A', { url: '/A', template: '<div class="A" ui-view="fwd"></div>' })
.state('A.fwd', {
url: '/fwd', views: { 'fwd@A': {
template: '<div class="fwd" ui-view>',
controller: function($state) { if (count++ < 20 && $state.current.name == 'A.fwd') $state.go(".nest"); }
}}
})
.state('A.fwd.nest', { url: '/nest', template: '<div class="nest"></div>' });
}));

beforeEach(inject(function($document) {
document = $document[0];
}));

it('should not go into an infinite loop when controller uses $state.go', inject(function($rootScope, $q, $compile, $state) {
el = angular.element('<div><ui-view></ui-view></div>');
template = $compile(el)($rootScope);
$rootScope.$digest();

$state.transitionTo('aside');
$q.flush();
expect(template[0].querySelector('.aside')).toBeDefined();
expect(template[0].querySelector('.fwd')).toBeNull();

$state.transitionTo('A');
$q.flush();
expect(template[0].querySelector('.A')).not.toBeNull();
expect(template[0].querySelector('.fwd')).toBeNull();

$state.transitionTo('A.fwd');
$q.flush();
expect(template[0].querySelector('.A')).not.toBeNull();
expect(template[0].querySelector('.fwd')).not.toBeNull();
expect(template[0].querySelector('.nest')).not.toBeNull();
expect(count).toBe(1);
}));
});

0 comments on commit e13988b

Please sign in to comment.