@@ -7,6 +7,7 @@ import * as viewModule from './view';
77import { BindingPropagationConfig , Locals } from 'angular2/change_detection' ;
88
99import * as renderApi from 'angular2/src/render/api' ;
10+ import { ViewFactory } from 'angular2/src/core/compiler/view_factory' ;
1011
1112/**
1213 * A dehydrated view is a state of the view that allows it to be moved around
@@ -27,13 +28,17 @@ import * as renderApi from 'angular2/src/render/api';
2728@Injectable ( )
2829export class AppViewHydrator {
2930 _renderer :renderApi . Renderer ;
31+ _viewFactory :ViewFactory ;
3032
31- constructor ( renderer :renderApi . Renderer ) {
33+ constructor ( renderer :renderApi . Renderer , viewFactory : ViewFactory ) {
3234 this . _renderer = renderer ;
35+ this . _viewFactory = viewFactory ;
3336 }
3437
35- hydrateDynamicComponentView ( hostView : viewModule . AppView , boundElementIndex : number ,
38+ hydrateDynamicComponentView ( location : eli . ElementRef ,
3639 componentView :viewModule . AppView , componentDirective :eli . DirectiveBinding , injector :Injector ) {
40+ var hostView = location . hostView ;
41+ var boundElementIndex = location . boundElementIndex ;
3742 var binder = hostView . proto . elementBinders [ boundElementIndex ] ;
3843 if ( ! binder . hasDynamicComponent ( ) ) {
3944 throw new BaseException ( `There is no dynamic component directive at element ${ boundElementIndex } ` ) ;
@@ -84,28 +89,37 @@ export class AppViewHydrator {
8489 // parentView.componentChildViews[boundElementIndex] = null;
8590 }
8691
87- hydrateInPlaceHostView ( parentView :viewModule . AppView , hostElementSelector , hostView :viewModule . AppView , injector :Injector ) {
92+ hydrateInPlaceHostView ( parentComponentLocation :eli . ElementRef ,
93+ hostElementSelector , hostView :viewModule . AppView , injector :Injector ) {
8894 var parentRenderViewRef = null ;
89- if ( isPresent ( parentView ) ) {
90- // Needed for user views
91- throw new BaseException ( 'Not yet supported' ) ;
95+ if ( isPresent ( parentComponentLocation ) ) {
96+ var parentView = parentComponentLocation . hostView . componentChildViews [ parentComponentLocation . boundElementIndex ] ;
97+ parentRenderViewRef = parentView . render ;
98+ parentView . changeDetector . addChild ( hostView . changeDetector ) ;
99+ ListWrapper . push ( parentView . imperativeHostViews , hostView ) ;
100+
101+ if ( isBlank ( injector ) ) {
102+ injector = parentComponentLocation . injector ;
103+ }
92104 }
105+
93106 var binder = hostView . proto . elementBinders [ 0 ] ;
94107 var shadowDomAppInjector = this . _createShadowDomAppInjector ( binder . componentDirective , injector ) ;
95108
96- // render views
97109 var renderViewRefs = this . _renderer . createInPlaceHostView ( parentRenderViewRef , hostElementSelector , hostView . proto . render ) ;
98110
99111 this . _viewHydrateRecurse (
100112 hostView , renderViewRefs , 0 , shadowDomAppInjector , null , new Object ( ) , null
101113 ) ;
102114 }
103115
104- dehydrateInPlaceHostView ( parentView : viewModule . AppView , hostView :viewModule . AppView ) {
116+ dehydrateInPlaceHostView ( parentComponentLocation : eli . ElementRef , hostView :viewModule . AppView ) {
105117 var parentRenderViewRef = null ;
106- if ( isPresent ( parentView ) ) {
107- // Needed for user views
108- throw new BaseException ( 'Not yet supported' ) ;
118+ if ( isPresent ( parentComponentLocation ) ) {
119+ var parentView = parentComponentLocation . hostView . componentChildViews [ parentComponentLocation . boundElementIndex ] ;
120+ parentRenderViewRef = parentView . render ;
121+ ListWrapper . remove ( parentView . imperativeHostViews , hostView ) ;
122+ parentView . changeDetector . removeChild ( hostView . changeDetector ) ;
109123 }
110124 var render = hostView . render ;
111125 this . _viewDehydrateRecurse ( hostView ) ;
@@ -137,7 +151,7 @@ export class AppViewHydrator {
137151 appInjector : Injector , hostElementInjector : eli . ElementInjector ,
138152 context : Object , locals :Locals ) :number {
139153 if ( view . hydrated ( ) ) throw new BaseException ( 'The view is already hydrated.' ) ;
140-
154+ view . viewHydrator = this ;
141155 view . render = renderComponentViewRefs [ renderComponentIndex ++ ] ;
142156
143157 view . context = context ;
@@ -215,12 +229,22 @@ export class AppViewHydrator {
215229 this . _viewDehydrateRecurse ( componentView ) ;
216230 var binder = view . proto . elementBinders [ i ] ;
217231 if ( binder . hasDynamicComponent ( ) ) {
218- view . componentChildViews [ i ] = null ;
219232 view . changeDetector . removeShadowDomChild ( componentView . changeDetector ) ;
233+ view . componentChildViews [ i ] = null ;
234+ this . _viewFactory . returnView ( componentView ) ;
220235 }
221236 }
222237 }
223238
239+ // imperativeHostViews
240+ for ( var i = 0 ; i < view . imperativeHostViews . length ; i ++ ) {
241+ var hostView = view . imperativeHostViews [ i ] ;
242+ this . _viewDehydrateRecurse ( hostView ) ;
243+ view . changeDetector . removeChild ( hostView . changeDetector ) ;
244+ this . _viewFactory . returnView ( hostView ) ;
245+ }
246+ view . imperativeHostViews = [ ] ;
247+
224248 // elementInjectors
225249 for ( var i = 0 ; i < view . elementInjectors . length ; i ++ ) {
226250 if ( isPresent ( view . elementInjectors [ i ] ) ) {
0 commit comments