OLD | NEW |
1 part of angular.directive; | 1 part of angular.directive; |
2 | 2 |
3 /** | 3 /** |
4 * Base class for NgIfAttrDirective and NgUnlessAttrDirective. | 4 * Base class for NgIf and NgUnless. |
5 */ | 5 */ |
6 abstract class _NgUnlessIfAttrDirectiveBase { | 6 abstract class _NgUnlessIfAttrDirectiveBase { |
7 final BoundBlockFactory _boundBlockFactory; | 7 final BoundViewFactory _boundViewFactory; |
8 final BlockHole _blockHole; | 8 final ViewPort _viewPort; |
9 final Scope _scope; | 9 final Scope _scope; |
10 | 10 |
11 Block _block; | 11 View _view; |
12 | 12 |
13 /** | 13 /** |
14 * The new child scope. This child scope is recreated whenever the `ng-if` | 14 * The new child scope. This child scope is recreated whenever the `ng-if` |
15 * subtree is inserted into the DOM and destroyed when it's removed from the | 15 * subtree is inserted into the DOM and destroyed when it's removed from the |
16 * DOM. Refer | 16 * DOM. Refer |
17 * https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-prototypica
l-Inheritance prototypical inheritance | 17 * https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-prototypica
l-Inheritance prototypical inheritance |
18 */ | 18 */ |
19 Scope _childScope; | 19 Scope _childScope; |
20 | 20 |
21 _NgUnlessIfAttrDirectiveBase(this._boundBlockFactory, this._blockHole, | 21 _NgUnlessIfAttrDirectiveBase(this._boundViewFactory, this._viewPort, |
22 this._scope); | 22 this._scope); |
23 | 23 |
24 // Override in subclass. | 24 // Override in subclass. |
25 set condition(value); | 25 void set condition(value); |
26 | 26 |
27 void _ensureBlockExists() { | 27 void _ensureViewExists() { |
28 if (_block == null) { | 28 if (_view == null) { |
29 _childScope = _scope.createChild(new PrototypeMap(_scope.context)); | 29 _childScope = _scope.createChild(new PrototypeMap(_scope.context)); |
30 _block = _boundBlockFactory(_childScope); | 30 _view = _boundViewFactory(_childScope); |
31 var insertBlock = _block; | 31 var view = _view; |
32 _scope.rootScope.domWrite(() { | 32 _scope.rootScope.domWrite(() { |
33 insertBlock.insertAfter(_blockHole); | 33 _viewPort.insert(view); |
34 }); | 34 }); |
35 } | 35 } |
36 } | 36 } |
37 | 37 |
38 void _ensureBlockDestroyed() { | 38 void _ensureViewDestroyed() { |
39 if (_block != null) { | 39 if (_view != null) { |
40 var removeBlock = _block; | 40 var view = _view; |
41 _scope.rootScope.domWrite(() { | 41 _scope.rootScope.domWrite(() { |
42 removeBlock.remove(); | 42 _viewPort.remove(view); |
43 }); | 43 }); |
44 _childScope.destroy(); | 44 _childScope.destroy(); |
45 _block = null; | 45 _view = null; |
46 _childScope = null; | 46 _childScope = null; |
47 } | 47 } |
48 } | 48 } |
49 } | 49 } |
50 | 50 |
51 | 51 |
52 /** | 52 /** |
53 * The `ng-if` directive compliments the `ng-unless` (provided by | 53 * The `ng-if` directive compliments the `ng-unless` (provided by |
54 * [NgUnlessAttrDirective]) directive. | 54 * [NgUnless]) directive. |
55 * | 55 * |
56 * directive based on the **truthy/falsy** value of the provided expression. | 56 * directive based on the **truthy/falsy** value of the provided expression. |
57 * Specifically, if the expression assigned to `ng-if` evaluates to a `false` | 57 * Specifically, if the expression assigned to `ng-if` evaluates to a `false` |
58 * value, then the subtree is removed from the DOM. Otherwise, *a clone of the | 58 * value, then the subtree is removed from the DOM. Otherwise, *a clone of the |
59 * subtree* is reinserted into the DOM. This clone is created from the compiled | 59 * subtree* is reinserted into the DOM. This clone is created from the compiled |
60 * state. As such, modifications made to the element after compilation (e.g. | 60 * state. As such, modifications made to the element after compilation (e.g. |
61 * changing the `class`) are lost when the element is destroyed. | 61 * changing the `class`) are lost when the element is destroyed. |
62 * | 62 * |
63 * Whenever the subtree is inserted into the DOM, it always gets a new child | 63 * Whenever the subtree is inserted into the DOM, it always gets a new child |
64 * scope. This child scope is destroyed when the subtree is removed from the | 64 * scope. This child scope is destroyed when the subtree is removed from the |
65 * DOM. Refer | 65 * DOM. Refer |
66 * https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-prototypical-
Inheritance prototypical inheritance | 66 * https://github.com/angular/angular.js/wiki/The-Nuances-of-Scope-prototypical-
Inheritance prototypical inheritance |
67 * | 67 * |
68 * This has an important implication when `ng-model` is used inside an `ng-if` | 68 * This has an important implication when `ng-model` is used inside an `ng-if` |
69 * to bind to a javascript primitive defined in the parent scope. In such a | 69 * to bind to a javascript primitive defined in the parent scope. In such a |
70 * situation, any modifications made to the variable in the `ng-if` subtree will | 70 * situation, any modifications made to the variable in the `ng-if` subtree will |
71 * be made on the child scope and override (hide) the value in the parent scope. | 71 * be made on the child scope and override (hide) the value in the parent scope. |
72 * The parent scope will remain unchanged by changes affected by this subtree. | 72 * The parent scope will remain unchanged by changes affected by this subtree. |
73 * | 73 * |
74 * Note: `ng-if` differs from `ng-show` and `ng-hide` in that `ng-if` completely | 74 * Note: `ng-if` differs from `ng-show` and `ng-hide` in that `ng-if` completely |
75 * removes and recreates the element in the DOM rather than changing its | 75 * removes and recreates the element in the DOM rather than changing its |
76 * visibility via the `display` css property. A common case when this | 76 * visibility via the `display` css property. A common case when this |
77 * difference is significant is when using css selectors that rely on an | 77 * difference is significant is when using css selectors that rely on an |
78 * element's position within the DOM (HTML), such as the `:first-child` or | 78 * element's position within the DOM (HTML), such as the `:first-child` or |
79 * `:last-child` pseudo-classes. | 79 * `:last-child` pseudo-classes. |
80 * | 80 * |
81 * Example: | 81 * Example: |
82 * | 82 * |
83 * <!-- By using ng-if instead of ng-show, we avoid the cost of the showdown | 83 * <!-- By using ng-if instead of ng-show, we avoid the cost of the showdown |
84 * filter, the repeater, etc. --> | 84 * formatter, the repeater, etc. --> |
85 * <div ng-if="showDetails"> | 85 * <div ng-if="showDetails"> |
86 * {{obj.details.markdownText | showdown}} | 86 * {{obj.details.markdownText | showdown}} |
87 * <div ng-repeat="item in obj.details.items"> | 87 * <div ng-repeat="item in obj.details.items"> |
88 * ... | 88 * ... |
89 * </div> | 89 * </div> |
90 * </div> | 90 * </div> |
91 */ | 91 */ |
92 @NgDirective( | 92 @Decorator( |
93 children: NgAnnotation.TRANSCLUDE_CHILDREN, | 93 children: Directive.TRANSCLUDE_CHILDREN, |
94 selector:'[ng-if]', | 94 selector:'[ng-if]', |
95 map: const {'.': '=>condition'}) | 95 map: const {'.': '=>condition'}) |
96 class NgIfDirective extends _NgUnlessIfAttrDirectiveBase { | 96 class NgIf extends _NgUnlessIfAttrDirectiveBase { |
97 NgIfDirective(BoundBlockFactory boundBlockFactory, | 97 NgIf(BoundViewFactory boundViewFactory, |
98 BlockHole blockHole, | 98 ViewPort viewPort, |
99 Scope scope): super(boundBlockFactory, blockHole, scope); | 99 Scope scope): super(boundViewFactory, viewPort, scope); |
100 | 100 |
101 set condition(value) { | 101 void set condition(value) { |
102 if (toBool(value)) { | 102 if (toBool(value)) { |
103 _ensureBlockExists(); | 103 _ensureViewExists(); |
104 } else { | 104 } else { |
105 _ensureBlockDestroyed(); | 105 _ensureViewDestroyed(); |
106 } | 106 } |
107 } | 107 } |
108 } | 108 } |
109 | 109 |
110 | 110 |
111 /** | 111 /** |
112 * The `ng-unless` directive compliments the `ng-if` (provided by | 112 * The `ng-unless` directive complements the `ng-if` (provided by |
113 * [NgIfAttrDirective]) directive. | 113 * [NgIf]) directive. |
114 * | 114 * |
115 * The `ng-unless` directive recreates/destroys the DOM subtree containing the | 115 * The `ng-unless` directive recreates/destroys the DOM subtree containing the |
116 * directive based on the **falsy/truthy** value of the provided expression. | 116 * directive based on the **falsy/truthy** value of the provided expression. |
117 * Specifically, if the expression assigned to `ng-unless` evaluates to a `true` | 117 * Specifically, if the expression assigned to `ng-unless` evaluates to a `true` |
118 * value, then the subtree is removed from the DOM. Otherwise, *a clone of the | 118 * value, then the subtree is removed from the DOM. Otherwise, *a clone of the |
119 * subtree* is reinserted into the DOM. This clone is created from the compiled | 119 * subtree* is reinserted into the DOM. This clone is created from the compiled |
120 * state. As such, modifications made to the element after compilation (e.g. | 120 * state. As such, modifications made to the element after compilation (e.g. |
121 * changing the `class`) are lost when the element is destroyed. | 121 * changing the `class`) are lost when the element is destroyed. |
122 * | 122 * |
123 * Whenever the subtree is inserted into the DOM, it always gets a new child | 123 * Whenever the subtree is inserted into the DOM, it always gets a new child |
(...skipping 10 matching lines...) Expand all Loading... |
134 * | 134 * |
135 * Note: `ng-unless` differs from `ng-show` and `ng-hide` in that `ng-unless` | 135 * Note: `ng-unless` differs from `ng-show` and `ng-hide` in that `ng-unless` |
136 * completely removes and recreates the element in the DOM rather than changing | 136 * completely removes and recreates the element in the DOM rather than changing |
137 * its visibility via the `display` css property. A common case when this | 137 * its visibility via the `display` css property. A common case when this |
138 * difference is significant is when using css selectors that rely on an | 138 * difference is significant is when using css selectors that rely on an |
139 * element's position within the DOM (HTML), such as the `:first-child` or | 139 * element's position within the DOM (HTML), such as the `:first-child` or |
140 * `:last-child` pseudo-classes. | 140 * `:last-child` pseudo-classes. |
141 * | 141 * |
142 * Example: | 142 * Example: |
143 * | 143 * |
144 * <!-- By using ng-unless instead of ng-show, we avoid the cost of the show
down | 144 * <!-- By using ng-unless instead of ng-show, we avoid the cost of the |
145 * filter, the repeater, etc. --> | 145 * showdown formatter, the repeater, etc. --> |
146 * <div ng-unless="terseView"> | 146 * <div ng-unless="terseView"> |
147 * {{obj.details.markdownText | showdown}} | 147 * {{obj.details.markdownText | showdown}} |
148 * <div ng-repeat="item in obj.details.items"> | 148 * <div ng-repeat="item in obj.details.items"> |
149 * ... | 149 * ... |
150 * </div> | 150 * </div> |
151 * </div> | 151 * </div> |
152 */ | 152 */ |
153 @NgDirective( | 153 @Decorator( |
154 children: NgAnnotation.TRANSCLUDE_CHILDREN, | 154 children: Directive.TRANSCLUDE_CHILDREN, |
155 selector:'[ng-unless]', | 155 selector:'[ng-unless]', |
156 map: const {'.': '=>condition'}) | 156 map: const {'.': '=>condition'}) |
157 class NgUnlessDirective extends _NgUnlessIfAttrDirectiveBase { | 157 class NgUnless extends _NgUnlessIfAttrDirectiveBase { |
158 | 158 |
159 NgUnlessDirective(BoundBlockFactory boundBlockFactory, | 159 NgUnless(BoundViewFactory boundViewFactory, |
160 BlockHole blockHole, | 160 ViewPort viewPort, |
161 Scope scope): super(boundBlockFactory, blockHole, scope); | 161 Scope scope): super(boundViewFactory, viewPort, scope); |
162 | 162 |
163 set condition(value) { | 163 void set condition(value) { |
164 if (!toBool(value)) { | 164 if (!toBool(value)) { |
165 _ensureBlockExists(); | 165 _ensureViewExists(); |
166 } else { | 166 } else { |
167 _ensureBlockDestroyed(); | 167 _ensureViewDestroyed(); |
168 } | 168 } |
169 } | 169 } |
170 } | 170 } |
OLD | NEW |