-
Notifications
You must be signed in to change notification settings - Fork 6.7k
feat(tabs): makes deselect callback fire before select. fixes #1557. #1566
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,7 +73,7 @@ describe('tabs', function() { | |
expect(titles().eq(0)).toHaveClass('active'); | ||
expect(titles().eq(1)).not.toHaveClass('active'); | ||
expect(scope.actives.one).toBe(true); | ||
expect(scope.actives.two).toBe(false); | ||
expect(scope.actives.two).not.toBeDefined(); | ||
}); | ||
|
||
it('should change active on click', function() { | ||
|
@@ -99,7 +99,6 @@ describe('tabs', function() { | |
titles().eq(1).find('a').click(); | ||
expect(scope.deselectFirst).toHaveBeenCalled(); | ||
}); | ||
|
||
}); | ||
|
||
describe('basics with initial active tab', function() { | ||
|
@@ -153,6 +152,48 @@ describe('tabs', function() { | |
}); | ||
}); | ||
|
||
describe('tab callback order', function() { | ||
var execOrder; | ||
beforeEach(inject(function($compile, $rootScope) { | ||
scope = $rootScope.$new(); | ||
execOrder = []; | ||
scope.actives = {}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So you have to add: |
||
|
||
scope.execute = function(id) { | ||
execOrder.push(id); | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of creating multiple function to do the same, I would have just: scope.execute = function(id) {
execOrder.push(id);
}; |
||
|
||
elm = $compile([ | ||
'<div>', | ||
' <tabset class="hello" data-pizza="pepperoni">', | ||
' <tab heading="First Tab" active="actives.one" select="execute(\'select1\')" deselect="execute(\'deselect1\')"></tab>', | ||
' <tab select="execute(\'select2\')" deselect="execute(\'deselect2\')"></tab>', | ||
' </tabset>', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So here you can have it like: '<tab heading="First Tab" active="actives.one" select="execute(\'select1\')" deselect="execute(\'deselect1\')"></tab>',
' <tab select="execute(\'select2\')" deselect="execute(\'deselect2\')"></tab>', |
||
'</div>' | ||
].join('\n'))(scope); | ||
scope.$apply(); | ||
return elm; | ||
})); | ||
|
||
it('should call select for the first tab', function() { | ||
expect(execOrder).toEqual([ 'select1' ]); | ||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would break this into two tests and I would also change the comparisons to make it more readable. Something like: it('should call select for the first tab', function() {
expect(execOrder).toEqual([ 'select1' ]);
});
it('should call deselect, then select', function() {
execOrder = [];
// Select second tab
titles().eq(1).find('a').click();
expect(execOrder).toEqual([ 'deselect1', 'select2' ]);
execOrder = [];
// Select again first tab
titles().eq(0).find('a').click();
expect(execOrder).toEqual([ 'deselect2', 'select1' ]);
}); |
||
|
||
it('should call deselect, then select', function() { | ||
execOrder = []; | ||
|
||
// Select second tab | ||
titles().eq(1).find('a').click(); | ||
expect(execOrder).toEqual([ 'deselect1', 'select2' ]); | ||
|
||
execOrder = []; | ||
|
||
// Select again first tab | ||
titles().eq(0).find('a').click(); | ||
expect(execOrder).toEqual([ 'deselect2', 'select1' ]); | ||
}); | ||
}); | ||
|
||
describe('ng-repeat', function() { | ||
|
||
beforeEach(inject(function($compile, $rootScope) { | ||
|
@@ -346,7 +387,11 @@ describe('tabs', function() { | |
|
||
describe('tabset controller', function() { | ||
function mockTab(isActive) { | ||
return { active: !!isActive }; | ||
return { | ||
active: !!isActive, | ||
onSelect : angular.noop, | ||
onDeselect : angular.noop | ||
}; | ||
} | ||
|
||
var ctrl; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jroxendal Is there a way that this function will be called on already active tab? What I mean do we really need the double check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As the code is written now, this is necessary. On tab click, active is set to true. The active watch is then run, where this function is called and at this time two tabs may actually be active: the 'old' tab (which should be deselected) and the one we just selected. Only one of the deselect callbacks should be run, obviously.
I didn't want to do a complete rewrite, so I left the active watch in the tabs directive in there. In order to avoid the check above, I believe that watch needs to go and some further refractoring to take place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you are right about the 2 active tabs, so the double check is needed.