fix(dynamic_component_loader): implemented dispose for dynamically-loaded components
This commit is contained in:
parent
9613772455
commit
21dcfc89e9
|
@ -43,7 +43,7 @@ export class DynamicComponentLoader {
|
|||
this._viewManager.createDynamicComponentView(location, componentProtoViewRef, binding,
|
||||
injector);
|
||||
var component = this._viewManager.getComponent(location);
|
||||
var dispose = () => { throw new BaseException("Not implemented"); };
|
||||
var dispose = () => { this._viewManager.destroyDynamicComponent(location); };
|
||||
return new ComponentRef(location, component, dispose);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -688,22 +688,20 @@ export class ElementInjector extends TreeNode<ElementInjector> {
|
|||
this._preBuiltObjects = null;
|
||||
this._lightDomAppInjector = null;
|
||||
this._shadowDomAppInjector = null;
|
||||
|
||||
this._strategy.callOnDestroy();
|
||||
|
||||
if (isPresent(this._dynamicallyCreatedComponentBinding) &&
|
||||
this._dynamicallyCreatedComponentBinding.callOnDestroy) {
|
||||
this._dynamicallyCreatedComponent.onDestroy();
|
||||
}
|
||||
|
||||
this.destroyDynamicComponent();
|
||||
this._strategy.clearInstances();
|
||||
|
||||
this._dynamicallyCreatedComponent = null;
|
||||
this._dynamicallyCreatedComponentBinding = null;
|
||||
|
||||
this._constructionCounter = 0;
|
||||
}
|
||||
|
||||
destroyDynamicComponent(): void {
|
||||
if (isPresent(this._dynamicallyCreatedComponentBinding) &&
|
||||
this._dynamicallyCreatedComponentBinding.callOnDestroy) {
|
||||
this._dynamicallyCreatedComponent.onDestroy();
|
||||
this._dynamicallyCreatedComponentBinding = null;
|
||||
this._dynamicallyCreatedComponent = null;
|
||||
}
|
||||
}
|
||||
|
||||
hydrate(injector: Injector, host: ElementInjector, preBuiltObjects: PreBuiltObjects): void {
|
||||
var p = this._proto;
|
||||
|
|
|
@ -133,6 +133,14 @@ export class AppViewManager {
|
|||
this._destroyFreeEmbeddedView(parentView, boundElementIndex, internalView(viewRef));
|
||||
}
|
||||
|
||||
destroyDynamicComponent(location: ElementRef) {
|
||||
var hostView = internalView(location.parentView);
|
||||
var ei = hostView.elementInjectors[location.boundElementIndex];
|
||||
var componentView = hostView.componentChildViews[location.boundElementIndex];
|
||||
ei.destroyDynamicComponent();
|
||||
this._destroyComponentView(hostView, location.boundElementIndex, componentView);
|
||||
}
|
||||
|
||||
createViewInContainer(viewContainerLocation: ElementRef, atIndex: number,
|
||||
protoViewRef: ProtoViewRef, context: ElementRef = null,
|
||||
injector: Injector = null): ViewRef {
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
|
||||
import {TestBed, ViewProxy} from 'angular2/src/test_lib/test_bed';
|
||||
import {Injector} from 'angular2/di';
|
||||
import {Component, View} from 'angular2/annotations';
|
||||
import {Component, View, onDestroy} from 'angular2/annotations';
|
||||
import * as viewAnn from 'angular2/src/core/annotations_impl/view';
|
||||
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
|
||||
import {ElementRef} from 'angular2/src/core/compiler/element_ref';
|
||||
|
@ -68,6 +68,28 @@ export function main() {
|
|||
});
|
||||
}));
|
||||
|
||||
it('should allow destroying dynamically-loaded components',
|
||||
inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||
tb.overrideView(MyComp, new viewAnn.View({
|
||||
template: '<dynamic-comp #dynamic></dynamic-comp>',
|
||||
directives: [DynamicComp]
|
||||
}));
|
||||
|
||||
tb.createView(MyComp).then((view) => {
|
||||
var dynamicComponent = view.rawView.locals.get("dynamic");
|
||||
dynamicComponent.done.then((ref) => {
|
||||
view.detectChanges();
|
||||
expect(view.rootNodes).toHaveText("hello");
|
||||
|
||||
ref.dispose();
|
||||
|
||||
expect(ref.instance.destroyed).toBe(true);
|
||||
expect(view.rootNodes).toHaveText("");
|
||||
async.done();
|
||||
});
|
||||
});
|
||||
}));
|
||||
|
||||
it('should allow to destroy and create them via viewcontainer directives',
|
||||
ijTestBed((tb: TestBed, async) => {
|
||||
tb.overrideView(MyComp, new viewAnn.View({
|
||||
|
@ -287,16 +309,23 @@ class DynamicComp {
|
|||
}
|
||||
}
|
||||
|
||||
@Component({selector: 'hello-cmp', appInjector: [DynamicallyCreatedComponentService]})
|
||||
@Component({
|
||||
selector: 'hello-cmp',
|
||||
appInjector: [DynamicallyCreatedComponentService],
|
||||
lifecycle: [onDestroy]
|
||||
})
|
||||
@View({template: "{{greeting}}"})
|
||||
class DynamicallyCreatedCmp {
|
||||
greeting: string;
|
||||
dynamicallyCreatedComponentService: DynamicallyCreatedComponentService;
|
||||
destroyed: boolean = false;
|
||||
|
||||
constructor(a: DynamicallyCreatedComponentService) {
|
||||
this.greeting = "hello";
|
||||
this.dynamicallyCreatedComponentService = a;
|
||||
}
|
||||
|
||||
onDestroy() { this.destroyed = true; }
|
||||
}
|
||||
|
||||
@Component({selector: 'dummy'})
|
||||
|
|
Loading…
Reference in New Issue