Skip to content
This repository was archived by the owner on Sep 5, 2024. It is now read-only.

Commit 2ad4776

Browse files
committed
feat(showHide): Introduce directives to notify child directives on hide/show.
Features extreme tail-hooking technology. review
1 parent 1ae16cb commit 2ad4776

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

src/components/showHide/showHide.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* @ngdoc module
3+
* @name material.components.showHide
4+
*/
5+
6+
// Add additional handlers to ng-show and ng-hide that notify directives
7+
// contained within that they should recompute their size.
8+
// These run in addition to Angular's built-in ng-hide and ng-show directives.
9+
angular.module('material.components.showHide', [
10+
'material.core'
11+
])
12+
.directive('ngShow', createDirective('ngShow', true))
13+
.directive('ngHide', createDirective('ngHide', false));
14+
15+
16+
function createDirective(name, targetValue) {
17+
return ['$mdUtil', function($mdUtil) {
18+
return {
19+
restrict: 'A',
20+
multiElement: true,
21+
link: function($scope, $element, $attr) {
22+
$scope.$watch($attr[name], function(value) {
23+
if (!!value === targetValue) {
24+
$scope.$broadcast('$md-resize');
25+
$mdUtil.dom.animator.waitTransitionEnd($element).then(function() {
26+
$scope.$broadcast('$md-resize');
27+
});
28+
}
29+
});
30+
}
31+
};
32+
}];
33+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
describe('showHide', function() {
2+
var $compile, defered, scope, spy;
3+
4+
beforeEach(module('material.components.showHide'));
5+
6+
beforeEach(inject(function(_$compile_, $mdUtil, $q, $rootScope) {
7+
$compile = _$compile_;
8+
defered = $q.defer();
9+
scope = $rootScope.$new();
10+
spy = jasmine.createSpy();
11+
12+
scope.$on('$md-resize', spy);
13+
spyOn($mdUtil.dom.animator, 'waitTransitionEnd').and.returnValue(defered.promise);
14+
}));
15+
16+
afterEach(function() {
17+
scope.$destroy();
18+
});
19+
20+
describe('ng-hide', function() {
21+
it('should notify when the node unhides', function() {
22+
scope.hide = true;
23+
var element = $compile('<div ng-hide="hide"></div>')(scope);
24+
scope.$apply();
25+
expect(spy).not.toHaveBeenCalled();
26+
27+
// Expect a $broadcast when showing.
28+
scope.hide = false;
29+
scope.$apply();
30+
expect(spy).toHaveBeenCalled();
31+
32+
// Expect a $broadcast on transitionEnd after showing.
33+
spy.calls.reset();
34+
defered.resolve();
35+
scope.$apply();
36+
expect(spy).toHaveBeenCalled();
37+
});
38+
39+
it('should not notify on hide', function() {
40+
scope.hide = true;
41+
var element = $compile('<div ng-hide="hide"></div>')(scope);
42+
scope.$apply();
43+
44+
// Expect no $broadcasts when hiding.
45+
expect(spy).not.toHaveBeenCalled();
46+
defered.resolve();
47+
scope.$apply();
48+
expect(spy).not.toHaveBeenCalled();
49+
});
50+
});
51+
52+
describe('ng-show', function() {
53+
it('should notify when the node unhides', function() {
54+
scope.show = false;
55+
var element = $compile('<div ng-show="show"></div>')(scope);
56+
scope.$apply();
57+
expect(spy).not.toHaveBeenCalled();
58+
59+
// Expect a $broadcast when showing.
60+
scope.show = true;
61+
scope.$apply();
62+
expect(spy).toHaveBeenCalled();
63+
64+
// Expect a $broadcast on transitionEnd after showing.
65+
spy.calls.reset();
66+
defered.resolve();
67+
scope.$apply();
68+
expect(spy).toHaveBeenCalled();
69+
});
70+
71+
it('should not notify on hide', function() {
72+
scope.show = false;
73+
var element = $compile('<div ng-show="show"></div>')(scope);
74+
scope.$apply();
75+
76+
// Expect no $broadcasts when hiding.
77+
expect(spy).not.toHaveBeenCalled();
78+
defered.resolve();
79+
scope.$apply();
80+
expect(spy).not.toHaveBeenCalled();
81+
});
82+
});
83+
});

0 commit comments

Comments
 (0)