Skip to content
Closed

Fix vc #1560

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions modules/angular2/src/core/compiler/view_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ export class AppViewManager {
parentRenderViewRef = parentView.render;
}
var hostViewRenderRef = hostView.render;
this._utils.dehydrateAndDetachInPlaceHostView(parentView, hostView);
this._viewDehydrateRecurse(hostView);
this._utils.detachInPlaceHostView(parentView, hostView);
this._renderer.destroyInPlaceHostView(parentRenderViewRef, hostViewRenderRef);
this._destroyView(hostView);
}
Expand All @@ -95,7 +95,6 @@ export class AppViewManager {
var boundElementIndex:number = viewContainerLocation.boundElementIndex;
var viewContainer = parentView.viewContainers[boundElementIndex];
var view = viewContainer.views[atIndex];
this._utils.dehydrateView(view);
this._viewDehydrateRecurse(view);
this._utils.detachViewInContainer(parentView, boundElementIndex, atIndex);
this._renderer.destroyViewInContainer(this._getRenderViewContainerRef(parentView, boundElementIndex), atIndex);
Expand Down Expand Up @@ -167,11 +166,11 @@ export class AppViewManager {
}

_viewDehydrateRecurse(view:viewModule.AppView) {
this._utils.dehydrateView(view);
var binders = view.proto.elementBinders;
for (var i = 0; i < binders.length; i++) {
var componentView = view.componentChildViews[i];
if (isPresent(componentView)) {
this._utils.dehydrateView(componentView);
this._viewDehydrateRecurse(componentView);
if (binders[i].hasDynamicComponent()) {
this._utils.detachComponentView(view, i);
Expand All @@ -182,7 +181,7 @@ export class AppViewManager {
if (isPresent(vc)) {
for (var j = vc.views.length - 1; j >= 0; j--) {
var childView = vc.views[j];
this._utils.dehydrateView(childView);
this._viewDehydrateRecurse(childView);
this._utils.detachViewInContainer(view, i, j);
this._destroyView(childView);
}
Expand All @@ -193,7 +192,7 @@ export class AppViewManager {
for (var i = 0; i < view.imperativeHostViews.length; i++) {
var hostView = view.imperativeHostViews[i];
this._viewDehydrateRecurse(hostView);
this._utils.dehydrateAndDetachInPlaceHostView(view, hostView);
this._utils.detachInPlaceHostView(view, hostView);
this._destroyView(hostView);
}
view.render = null;
Expand Down
4 changes: 1 addition & 3 deletions modules/angular2/src/core/compiler/view_manager_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,8 @@ export class AppViewManagerUtils {
this._hydrateView(hostView, injector, hostElementInjector, new Object(), null);
}

dehydrateAndDetachInPlaceHostView(parentView:viewModule.AppView,
detachInPlaceHostView(parentView:viewModule.AppView,
hostView:viewModule.AppView) {
this.dehydrateView(hostView);

if (isPresent(parentView)) {
parentView.changeDetector.removeChild(hostView.changeDetector);
ListWrapper.remove(parentView.imperativeHostViews, hostView);
Expand Down
4 changes: 3 additions & 1 deletion modules/angular2/src/render/dom/view/view_hydrator.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ export class RenderViewHydrator {

_viewContainerDehydrateRecurse(viewContainer) {
for (var i=0; i<viewContainer.views.length; i++) {
this._viewDehydrateRecurse(viewContainer.views[i]);
var view = viewContainer.views[i];
this._viewDehydrateRecurse(view);
this._viewFactory.returnView(view);
}
viewContainer.clear();
}
Expand Down
73 changes: 54 additions & 19 deletions modules/angular2/test/core/compiler/view_manager_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,15 @@ export function main() {

});

describe('recurse into static child component views', () => {
describe('recursively destroy dynamic child component views', () => {
// TODO
});

});

describe('static child components', () => {

describe('recursively create when not cached', () => {
var hostView, componentProtoView, nestedProtoView;
beforeEach( () => {
hostView = createView(createProtoView(
Expand Down Expand Up @@ -267,19 +275,16 @@ export function main() {
expect(renderer.spy('setEventDispatcher')).toHaveBeenCalledWith(cmpView.render, cmpView);
});
});
});

describe('createDynamicComponentView', () => {
// TODO: implement this!
describe('recurse into static child component views', () => {
// TODO
describe('recursively hydrate when getting from from the cache', () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add TODO to implement the test

// TODO(tbosch): implement this
});

describe('recurse into dynamic child component views', () => {
// TODO
describe('recursively dehydrate', () => {
// TODO(tbosch): implement this
});
});

});

describe('createInPlaceHostView', () => {

Expand Down Expand Up @@ -347,9 +352,14 @@ export function main() {
hostRenderViewRef = hostView.render;
});

it('should dehydrateAndDetach', () => {
it('should dehydrate', () => {
manager.destroyInPlaceHostView(elementRef(parentHostView, 0), hostView);
expect(utils.spy('detachInPlaceHostView')).toHaveBeenCalledWith(parentView, hostView);
});

it('should detach', () => {
manager.destroyInPlaceHostView(elementRef(parentHostView, 0), hostView);
expect(utils.spy('dehydrateAndDetachInPlaceHostView')).toHaveBeenCalledWith(parentView, hostView);
expect(utils.spy('dehydrateView')).toHaveBeenCalledWith(hostView);
});

it('should destroy and clear the render view', () => {
Expand All @@ -364,17 +374,14 @@ export function main() {
});
});

describe('recurse into imperativeHostViews', () => {
describe('recursively destroy inPlaceHostViews', () => {
// TODO
});

});

describe('createViewInContainer', () => {

// Note: We don't add tests for recursion or viewpool here as we assume that
// this is using the same mechanism as the other methods...

describe('basic functionality', () => {
var parentView, childProtoView;
beforeEach( () => {
Expand Down Expand Up @@ -425,8 +432,6 @@ export function main() {
});

describe('destroyViewInContainer', () => {
// Note: We don't add tests for recursion here as we assume that
// this is using the same mechanism as the other methods...

describe('basic functionality', () => {
var parentView, childProtoView, childView;
Expand Down Expand Up @@ -461,8 +466,38 @@ export function main() {
});
});

describe('recurse into ViewContainers', () => {
// TODO
describe('recursively destroy views in ViewContainers', () => {
var parentView, childProtoView, childView;
beforeEach( () => {
parentView = createView(createProtoView(
[createEmptyElBinder()]
));
parentView.render = new ViewRef();
childProtoView = createProtoView();
childView = manager.createViewInContainer(elementRef(parentView, 0), 0, childProtoView, null);
});

it('should dehydrate', () => {
manager.destroyInPlaceHostView(null, parentView);
expect(utils.spy('dehydrateView')).toHaveBeenCalledWith(parentView.viewContainers[0].views[0]);
});

it('should detach', () => {
manager.destroyInPlaceHostView(null, parentView);
expect(utils.spy('detachViewInContainer')).toHaveBeenCalledWith(parentView, 0, 0);
});

it('should not destroy but clear the render view', () => {
manager.destroyInPlaceHostView(null, parentView);
expect(renderer.spy('destroyViewInContainer')).not.toHaveBeenCalled();
expect(childView.render).toBe(null);
});

it('should return the view to the pool', () => {
manager.destroyInPlaceHostView(null, parentView);
expect(viewPool.spy('returnView')).toHaveBeenCalledWith(childView);
});

});

});
Expand Down
11 changes: 11 additions & 0 deletions modules/angular2/test/render/dom/view/view_hydrator_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,17 @@ export function main() {
expect(viewFactory.spy('returnView')).toHaveBeenCalledWith(shadowView);
});

it('should clear views in ViewContainers', () => {
createAndHydrate(null, null);
var vc = hostView.getOrCreateViewContainer(0);
var childView = createEmptyView();
vc.insert(childView);

dehydrate(hostView);

expect(viewFactory.spy('returnView')).toHaveBeenCalledWith(childView);
});

it('should clear imperatively added child components', () => {
var shadowView = createEmptyView();
createAndHydrate(createProtoView(), shadowView);
Expand Down