115
115
* <ui-view autoscroll='scopeVariable'/>
116
116
* </pre>
117
117
*/
118
- $ViewDirective . $inject = [ '$state' , '$compile' , '$controller' , '$ injector', '$uiViewScroll' , '$document '] ;
119
- function $ViewDirective ( $state , $compile , $controller , $ injector, $uiViewScroll , $document ) {
118
+ $ViewDirective . $inject = [ '$state' , '$injector' , '$uiViewScroll' ] ;
119
+ function $ViewDirective ( $state , $injector , $uiViewScroll ) {
120
120
121
121
function getService ( ) {
122
122
return ( $injector . has ) ? function ( service ) {
@@ -135,135 +135,98 @@ function $ViewDirective( $state, $compile, $controller, $injector, $ui
135
135
$animator = service ( '$animator' ) ,
136
136
$animate = service ( '$animate' ) ;
137
137
138
- // Returns a set of DOM manipulation functions based on whether animation
139
- // should be performed
140
- function getRenderer ( element , attrs , scope ) {
138
+ // Returns a set of DOM manipulation functions based on which Angular version
139
+ // it should use
140
+ function getRenderer ( attrs , scope ) {
141
141
var statics = function ( ) {
142
142
return {
143
- leave : function ( element ) { element . remove ( ) ; } ,
144
- enter : function ( element , parent , anchor ) { anchor . after ( element ) ; }
143
+ enter : function ( element , target ) { target . after ( element ) ; } ,
144
+ leave : function ( element ) { element . remove ( ) ; }
145
145
} ;
146
146
} ;
147
147
148
148
if ( $animate ) {
149
- return function ( shouldAnimate ) {
150
- return ! shouldAnimate ? statics ( ) : {
151
- enter : function ( element , parent , anchor ) { $animate . enter ( element , null , anchor ) ; } ,
152
- leave : function ( element ) { $animate . leave ( element , function ( ) { element . remove ( ) ; } ) ; }
153
- } ;
149
+ return {
150
+ enter : function ( element , target ) { $animate . enter ( element , null , target ) ; } ,
151
+ leave : function ( element ) { $animate . leave ( element ) ; }
154
152
} ;
155
153
}
156
154
157
155
if ( $animator ) {
158
156
var animate = $animator && $animator ( scope , attrs ) ;
159
157
160
- return function ( shouldAnimate ) {
161
- return ! shouldAnimate ? statics ( ) : {
162
- enter : function ( element , parent , anchor ) { animate . enter ( element , parent ) ; } ,
163
- leave : function ( element ) { animate . leave ( element . contents ( ) , element ) ; }
164
- } ;
158
+ return {
159
+ enter : function ( element , target ) { animate . enter ( element , null , target ) ; } ,
160
+ leave : function ( element ) { animate . leave ( element . contents ( ) , element ) ; }
165
161
} ;
166
162
}
167
163
168
- return statics ;
164
+ return statics ( ) ;
169
165
}
170
166
171
167
var directive = {
172
168
restrict : 'ECA' ,
173
- compile : function ( element , attrs ) {
174
- var initial = element . html ( ) ,
175
- isDefault = true ,
176
- anchor = angular . element ( $document [ 0 ] . createComment ( ' ui-view-anchor ' ) ) ,
177
- parentEl = element . parent ( ) ;
178
-
179
- element . prepend ( anchor ) ;
180
-
181
- return function ( $scope ) {
182
- var inherited = parentEl . inheritedData ( '$uiView' ) ;
183
-
169
+ terminal : true ,
170
+ priority : 400 ,
171
+ transclude : 'element' ,
172
+ compile : function ( tElement , tAttrs , $transclude ) {
173
+ return function ( scope , $element , attrs ) {
184
174
var currentScope , currentEl , viewLocals ,
185
- name = attrs [ directive . name ] || attrs . name || '' ,
186
- onloadExp = attrs . onload || '' ,
175
+ loaded = false ,
176
+ onloadExp = attrs . onload || '' ,
187
177
autoscrollExp = attrs . autoscroll ,
188
- renderer = getRenderer ( element , attrs , $scope ) ;
178
+ renderer = getRenderer ( attrs , scope ) ,
179
+ parentEl = $element . parent ( ) ,
180
+ inherited = parentEl . inheritedData ( '$uiView' ) ,
181
+ name = attrs [ directive . name ] || attrs . name || '' ;
189
182
190
183
if ( name . indexOf ( '@' ) < 0 ) name = name + '@' + ( inherited ? inherited . state . name : '' ) ;
191
- var view = { name : name , state : null } ;
192
184
193
185
var eventHook = function ( ) {
194
186
if ( viewIsUpdating ) return ;
187
+
195
188
viewIsUpdating = true ;
196
189
197
- try { updateView ( true ) ; } catch ( e ) {
198
- viewIsUpdating = false ;
190
+ try { updateView ( ) ; } catch ( e ) {
199
191
throw e ;
192
+ } finally {
193
+ viewIsUpdating = false ;
200
194
}
201
- viewIsUpdating = false ;
202
195
} ;
203
196
204
- $scope . $on ( '$stateChangeSuccess' , eventHook ) ;
205
- $scope . $on ( '$viewContentLoading' , eventHook ) ;
206
-
207
- updateView ( false ) ;
197
+ scope . $on ( '$stateChangeSuccess' , eventHook ) ;
198
+ scope . $on ( '$viewContentLoading' , eventHook ) ;
199
+ updateView ( ) ;
208
200
209
201
function cleanupLastView ( ) {
210
- if ( currentEl ) {
211
- renderer ( true ) . leave ( currentEl ) ;
212
- currentEl = null ;
213
- }
214
-
215
202
if ( currentScope ) {
216
203
currentScope . $destroy ( ) ;
217
204
currentScope = null ;
218
205
}
219
- }
220
-
221
- function updateView ( shouldAnimate ) {
222
- var locals = $state . $current && $state . $current . locals [ name ] ;
223
206
224
- if ( isDefault ) {
225
- isDefault = false ;
226
- element . replaceWith ( anchor ) ;
227
- }
228
-
229
- if ( ! locals ) {
230
- cleanupLastView ( ) ;
231
- currentEl = element . clone ( ) ;
232
- currentEl . html ( initial ) ;
233
- renderer ( shouldAnimate ) . enter ( currentEl , parentEl , anchor ) ;
234
-
235
- currentScope = $scope . $new ( ) ;
236
- $compile ( currentEl . contents ( ) ) ( currentScope ) ;
237
- return ;
207
+ if ( currentEl ) {
208
+ renderer . leave ( currentEl ) ;
209
+ currentEl = null ;
238
210
}
211
+ }
239
212
240
- if ( locals === viewLocals ) return ; // nothing to do
241
-
242
- cleanupLastView ( ) ;
243
-
244
- currentEl = element . clone ( ) ;
245
- currentEl . html ( locals . $template ? locals . $template : initial ) ;
246
- renderer ( true ) . enter ( currentEl , parentEl , anchor ) ;
213
+ function updateView ( ) {
214
+ var newScope = scope . $new ( ) ,
215
+ locals = $state . $current && $state . $current . locals [ name ] ;
247
216
248
- currentEl . data ( '$uiView' , view ) ;
217
+ if ( loaded && locals === viewLocals ) return ; // nothing to do
249
218
219
+ loaded = true ;
250
220
viewLocals = locals ;
251
- view . state = locals . $$state ;
252
221
253
- var link = $compile ( currentEl . contents ( ) ) ;
254
-
255
- currentScope = $scope . $new ( ) ;
256
-
257
- if ( locals . $$controller ) {
258
- locals . $scope = currentScope ;
259
- var controller = $controller ( locals . $$controller , locals ) ;
260
- if ( $state . $current . controllerAs ) {
261
- currentScope [ $state . $current . controllerAs ] = controller ;
262
- }
263
- currentEl . children ( ) . data ( '$ngControllerController' , controller ) ;
264
- }
222
+ var clone = $transclude ( newScope , function ( clone ) {
223
+ clone . data ( '$uiViewName' , name ) ;
224
+ renderer . enter ( clone , currentEl || $element ) ;
225
+ cleanupLastView ( ) ;
226
+ } ) ;
265
227
266
- link ( currentScope ) ;
228
+ currentEl = clone ;
229
+ currentScope = newScope ;
267
230
268
231
/**
269
232
* @ngdoc event
@@ -278,7 +241,7 @@ function $ViewDirective( $state, $compile, $controller, $injector, $ui
278
241
currentScope . $emit ( '$viewContentLoaded' ) ;
279
242
if ( onloadExp ) currentScope . $eval ( onloadExp ) ;
280
243
281
- if ( ! angular . isDefined ( autoscrollExp ) || ! autoscrollExp || $ scope. $eval ( autoscrollExp ) ) {
244
+ if ( ! angular . isDefined ( autoscrollExp ) || ! autoscrollExp || scope . $eval ( autoscrollExp ) ) {
282
245
$uiViewScroll ( currentEl ) ;
283
246
}
284
247
}
@@ -289,4 +252,43 @@ function $ViewDirective( $state, $compile, $controller, $injector, $ui
289
252
return directive ;
290
253
}
291
254
255
+ $ViewDirectiveFill . $inject = [ '$compile' , '$controller' , '$state' ] ;
256
+ function $ViewDirectiveFill ( $compile , $controller , $state ) {
257
+ return {
258
+ restrict : 'ECA' ,
259
+ priority : - 400 ,
260
+ compile : function ( tElement ) {
261
+ var initial = tElement . html ( ) ;
262
+
263
+ return function ( scope , $element ) {
264
+ var current = $state . $current ,
265
+ name = $element . data ( '$uiViewName' ) ,
266
+ locals = current && current . locals [ name ] ;
267
+
268
+ if ( ! locals ) {
269
+ return ;
270
+ }
271
+
272
+ $element . data ( '$uiView' , { name : name , state : locals . $$state } ) ;
273
+ $element . html ( locals . $template ? locals . $template : initial ) ;
274
+
275
+ var link = $compile ( $element . contents ( ) ) ;
276
+
277
+ if ( locals . $$controller ) {
278
+ locals . $scope = scope ;
279
+ var controller = $controller ( locals . $$controller , locals ) ;
280
+ if ( current . controllerAs ) {
281
+ scope [ current . controllerAs ] = controller ;
282
+ }
283
+ $element . data ( '$ngControllerController' , controller ) ;
284
+ $element . children ( ) . data ( '$ngControllerController' , controller ) ;
285
+ }
286
+
287
+ link ( scope ) ;
288
+ } ;
289
+ }
290
+ } ;
291
+ }
292
+
292
293
angular . module ( 'ui.router.state' ) . directive ( 'uiView' , $ViewDirective ) ;
294
+ angular . module ( 'ui.router.state' ) . directive ( 'uiView' , $ViewDirectiveFill ) ;
0 commit comments