Skip to content

Commit

Permalink
refactor the algorithm of sequential updating of nested segments if a…
Browse files Browse the repository at this point in the history
…ll of them have some resolving
  • Loading branch information
artch committed Aug 29, 2013
1 parent c2ca74a commit 7513eed
Show file tree
Hide file tree
Showing 2 changed files with 171 additions and 10 deletions.
38 changes: 29 additions & 9 deletions src/route-segment.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,19 +206,30 @@ angular.module( 'route-segment', [] ).provider( '$routeSegment',
// if we went back to the same state as we were before resolving new segment
resolvingSemaphoreChain[i] = newSegment.name;
else
updates.push(updateSegment(i, newSegment));
updates.push({index: i, newSegment: newSegment});
}
}

$q.all(updates).then(function(result) {
var curSegmentPromise = $q.when();

$routeSegment.name = segmentName;
$routeSegment.$routeParams = angular.copy($routeParams);
if(updates.length > 0) {
for(var i=0; i<updates.length; i++) {
(function(i) {
curSegmentPromise = curSegmentPromise.then(function() {

for(var i=0; i < result.length; i++) {
if(result[i].success != undefined)
broadcast(result[i].success);
return updateSegment(updates[i].index, updates[i].newSegment);

}).then(function(result) {

if(result.success != undefined) {
broadcast(result.success);
}
})
})(i);
}
}

curSegmentPromise.then(function() {

// Removing redundant segment in case if new segment chain is shorter than old one
if($routeSegment.chain.length > segmentNameChain.length) {
Expand All @@ -228,7 +239,8 @@ angular.module( 'route-segment', [] ).provider( '$routeSegment',
for(var i=segmentNameChain.length; i < oldLength; i++)
updateSegment(i, null);
}
});
})



}
Expand Down Expand Up @@ -258,7 +270,7 @@ angular.module( 'route-segment', [] ).provider( '$routeSegment',
}

resolvingSemaphoreChain[index] = segment.name;

if(segment.params.untilResolved) {
return resolve(index, segment.name, segment.params.untilResolved)
.then(function(result) {
Expand Down Expand Up @@ -348,6 +360,14 @@ angular.module( 'route-segment', [] ).provider( '$routeSegment',
}

function broadcast(index) {

$routeSegment.$routeParams = angular.copy($routeParams);

$routeSegment.name = '';
for(var i=0; i<$routeSegment.chain.length; i++)
$routeSegment.name += $routeSegment.chain[i].name+".";
$routeSegment.name = $routeSegment.name.substr(0, $routeSegment.name.length-1);

$rootScope.$broadcast( 'routeSegmentChange', {
index: index,
segment: $routeSegment.chain[index] || null } );
Expand Down
143 changes: 142 additions & 1 deletion test/unit/route-segment.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,6 @@ describe('route segment', function() {
$rootScope.$digest();
expect(callback).not.toHaveBeenCalled();
expect($routeSegment.$routeParams.id).toBe('1');
expect($routeSegment.$routeParams.tab).toBe('edit');

callback = jasmine.createSpy('event');
$rootScope.$on('routeSegmentChange', callback);
Expand Down Expand Up @@ -612,6 +611,148 @@ describe('route segment', function() {
expect(callback.calls[0].args[1].segment.params.stage).toBe('ERROR');
})
})

describe('resolving nested segment in series when all levels have some resolving', function() {

var defers;
beforeEach(inject(function($q) {
defers = [];
defers.push($q.defer());
defers.push($q.defer());
defers.push($q.defer());
$routeSegmentProvider.segment('section3', {
stage: 'AFTER',
resolve: {
data: function() {
return defers[0].promise;
}
},
untilResolved: {
stage: 'BEFORE'
}
})
$routeSegmentProvider.within('section3').segment('section31', {
stage: 'AFTER',
resolve: {
data: function() {
return defers[1].promise;
}
},
untilResolved: {
stage: 'BEFORE'
}
})
$routeSegmentProvider.within('section3').within('section31').segment('section311', {
stage: 'AFTER',
resolve: {
data: function() {
return defers[2].promise;
}
},
untilResolved: {
stage: 'BEFORE'
}
})
$routeSegmentProvider.when('/3/1', 'section3.section31');
$routeSegmentProvider.when('/3/1/1', 'section3.section31.section311');
}))

function expectSegmentChangeCall(callIndex, segmentName, segmentStage) {
expect(callback.calls[callIndex].args[1].segment.name).toBe(segmentName);
expect(callback.calls[callIndex].args[1].segment.params.stage).toBe(segmentStage);
}

it('should work in order 0-1-2', function() {
$location.path('/3/1/1');

$rootScope.$digest();
expect(callback.calls.length).toBe(1);
expectSegmentChangeCall(0, 'section3', 'BEFORE');
expect($routeSegment.name).toBe('section3');
expect($routeSegment.chain.length).toBe(1);

defers[0].resolve();

$rootScope.$digest();
expect(callback.calls.length).toBe(3);
expectSegmentChangeCall(1, 'section3', 'AFTER');
expectSegmentChangeCall(2, 'section31', 'BEFORE');
expect($routeSegment.name).toBe('section3.section31');
expect($routeSegment.chain.length).toBe(2);

defers[1].resolve();

$rootScope.$digest();
expect(callback.calls.length).toBe(5);
expectSegmentChangeCall(3, 'section31', 'AFTER');
expectSegmentChangeCall(4, 'section311', 'BEFORE');
expect($routeSegment.name).toBe('section3.section31.section311');
expect($routeSegment.chain.length).toBe(3);

defers[2].resolve();

$rootScope.$digest();
expect(callback.calls.length).toBe(6);
expectSegmentChangeCall(5, 'section311', 'AFTER');
expect($routeSegment.name).toBe('section3.section31.section311');
})

it('should work in order 0-2-1', function() {
$location.path('/3/1/1');
defers[0].resolve();
$rootScope.$digest();

defers[2].resolve();

$rootScope.$digest();
expect(callback.calls.length).toBe(3);
expectSegmentChangeCall(0, 'section3', 'BEFORE');
expectSegmentChangeCall(1, 'section3', 'AFTER');
expectSegmentChangeCall(2, 'section31', 'BEFORE');
expect($routeSegment.name).toBe('section3.section31');
expect($routeSegment.chain.length).toBe(2);

defers[1].resolve();

$rootScope.$digest();
expect(callback.calls.length).toBe(6);
expectSegmentChangeCall(3, 'section31', 'AFTER');
expectSegmentChangeCall(4, 'section311', 'BEFORE');
expectSegmentChangeCall(5, 'section311', 'AFTER');
expect($routeSegment.name).toBe('section3.section31.section311');
expect($routeSegment.chain.length).toBe(3);
})

it('should work in order 2-1-0', function() {
$location.path('/3/1/1');
$rootScope.$digest();

defers[2].resolve();

$rootScope.$digest();
expect(callback.calls.length).toBe(1);
expectSegmentChangeCall(0, 'section3', 'BEFORE');

defers[1].resolve();

$rootScope.$digest();
expect(callback.calls.length).toBe(1);

defers[0].resolve();

$rootScope.$digest();
expect(callback.calls.length).toBe(6);
expectSegmentChangeCall(1, 'section3', 'AFTER');
expectSegmentChangeCall(2, 'section31', 'BEFORE');
expectSegmentChangeCall(3, 'section31', 'AFTER');
expectSegmentChangeCall(4, 'section311', 'BEFORE');
expectSegmentChangeCall(5, 'section311', 'AFTER');
expect($routeSegment.name).toBe('section3.section31.section311');
expect($routeSegment.chain.length).toBe(3);
})

})

})


Expand Down

0 comments on commit 7513eed

Please sign in to comment.