-
Notifications
You must be signed in to change notification settings - Fork 3.4k
feat(showHide): Introduce directives to notify child directives on hi… #5579
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 |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** | ||
* @ngdoc module | ||
* @name material.components.showHide | ||
*/ | ||
|
||
// Add additional handlers to ng-show and ng-hide that notify directives | ||
// contained within that they should recompute their size. | ||
// These run in addition to Angular's built-in ng-hide and ng-show directives. | ||
angular.module('material.components.showHide', [ | ||
'material.core' | ||
]) | ||
.directive('ngShow', createDirective('ngShow', true)) | ||
.directive('ngHide', createDirective('ngHide', false)); | ||
|
||
|
||
function createDirective(name, targetValue) { | ||
return ['$mdUtil', function($mdUtil) { | ||
return { | ||
restrict: 'A', | ||
multiElement: true, | ||
link: function($scope, $element, $attr) { | ||
$scope.$watch($attr[name], function(value) { | ||
if (!!value === targetValue) { | ||
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. 👍 |
||
$mdUtil.nextTick(function() { | ||
$scope.$broadcast('$md-resize'); | ||
}); | ||
$mdUtil.dom.animator.waitTransitionEnd($element).then(function() { | ||
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. 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. Yeah, my concern was that not every element has transitions, and 3s is longer than I'd like to wait in those cases. |
||
$scope.$broadcast('$md-resize'); | ||
}); | ||
} | ||
}); | ||
} | ||
}; | ||
}]; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
describe('showHide', function() { | ||
var $compile, $timeout, defered, scope, spy; | ||
|
||
beforeEach(module('material.components.showHide')); | ||
|
||
beforeEach(inject(function(_$compile_, $mdUtil, $q, $rootScope, _$timeout_) { | ||
$compile = _$compile_; | ||
$timeout = _$timeout_; | ||
defered = $q.defer(); | ||
scope = $rootScope.$new(); | ||
spy = jasmine.createSpy(); | ||
|
||
scope.$on('$md-resize', spy); | ||
spyOn($mdUtil.dom.animator, 'waitTransitionEnd').and.returnValue(defered.promise); | ||
})); | ||
|
||
afterEach(function() { | ||
scope.$destroy(); | ||
}); | ||
|
||
describe('ng-hide', function() { | ||
it('should notify when the node unhides', function() { | ||
scope.hide = true; | ||
var element = $compile('<div ng-hide="hide"></div>')(scope); | ||
scope.$apply(); | ||
expect(spy).not.toHaveBeenCalled(); | ||
|
||
// Expect a $broadcast when showing. | ||
scope.hide = false; | ||
scope.$apply(); | ||
$timeout.flush(); | ||
expect(spy).toHaveBeenCalled(); | ||
|
||
// Expect a $broadcast on transitionEnd after showing. | ||
spy.calls.reset(); | ||
defered.resolve(); | ||
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. What are you doing here... it is not clear. 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. Added comments |
||
scope.$apply(); | ||
expect(spy).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should not notify on hide', function() { | ||
scope.hide = true; | ||
var element = $compile('<div ng-hide="hide"></div>')(scope); | ||
scope.$apply(); | ||
|
||
// Expect no $broadcasts when hiding. | ||
expect(spy).not.toHaveBeenCalled(); | ||
defered.resolve(); | ||
scope.$apply(); | ||
expect(spy).not.toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
describe('ng-show', function() { | ||
it('should notify when the node unhides', function() { | ||
scope.show = false; | ||
var element = $compile('<div ng-show="show"></div>')(scope); | ||
scope.$apply(); | ||
expect(spy).not.toHaveBeenCalled(); | ||
|
||
// Expect a $broadcast when showing. | ||
scope.show = true; | ||
scope.$apply(); | ||
$timeout.flush(); | ||
expect(spy).toHaveBeenCalled(); | ||
|
||
// Expect a $broadcast on transitionEnd after showing. | ||
spy.calls.reset(); | ||
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. Can you break this group out into a understand function call ? 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 think the comments added are sufficient. Have a look. |
||
defered.resolve(); | ||
scope.$apply(); | ||
expect(spy).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should not notify on hide', function() { | ||
scope.show = false; | ||
var element = $compile('<div ng-show="show"></div>')(scope); | ||
scope.$apply(); | ||
|
||
// Expect no $broadcasts when hiding. | ||
expect(spy).not.toHaveBeenCalled(); | ||
defered.resolve(); | ||
scope.$apply(); | ||
expect(spy).not.toHaveBeenCalled(); | ||
}); | ||
}); | ||
}); |
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.
I would move part of the later comment here, saying something like
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.
Done