diff --git a/src/lib/core/portal/dom-portal-host.ts b/src/lib/core/portal/dom-portal-host.ts index 2a0acab45a98..2e2424fa15b8 100644 --- a/src/lib/core/portal/dom-portal-host.ts +++ b/src/lib/core/portal/dom-portal-host.ts @@ -43,27 +43,36 @@ export class DomPortalHost extends BasePortalHost { } else { componentRef = componentFactory.create(portal.injector || this._defaultInjector); - // When creating a component outside of a ViewContainer, we need to manually register - // its ChangeDetector with the application. This API is unfortunately not yet published - // in Angular core. The change detector must also be deregistered when the component - // is destroyed to prevent memory leaks. - // - // See https://github.com/angular/angular/pull/12674 - let changeDetectorRef = componentRef.changeDetectorRef; - (this._appRef as any).registerChangeDetector(changeDetectorRef); - - this.setDisposeFn(() => { - (this._appRef as any).unregisterChangeDetector(changeDetectorRef); - - // Normally the ViewContainer will remove the component's nodes from the DOM. - // Without a ViewContainer, we need to manually remove the nodes. - let componentRootNode = this._getComponentRootNode(componentRef); - if (componentRootNode.parentNode) { - componentRootNode.parentNode.removeChild(componentRootNode); - } - - componentRef.destroy(); - }); + // ApplicationRef's attachView and detachView methods are in Angular ^2.2.1 but not before. + // The `else` clause here can be removed once 2.2.1 is released. + if ((this._appRef as any)['attachView']) { + (this._appRef as any).attachView(componentRef.hostView); + + this.setDisposeFn(() => { + (this._appRef as any).detachView(componentRef.hostView); + componentRef.destroy(); + }); + } else { + // When creating a component outside of a ViewContainer, we need to manually register + // its ChangeDetector with the application. This API is unfortunately not published + // in Angular <= 2.2.0. The change detector must also be deregistered when the component + // is destroyed to prevent memory leaks. + let changeDetectorRef = componentRef.changeDetectorRef; + (this._appRef as any).registerChangeDetector(changeDetectorRef); + + this.setDisposeFn(() => { + (this._appRef as any).unregisterChangeDetector(changeDetectorRef); + + // Normally the ViewContainer will remove the component's nodes from the DOM. + // Without a ViewContainer, we need to manually remove the nodes. + let componentRootNode = this._getComponentRootNode(componentRef); + if (componentRootNode.parentNode) { + componentRootNode.parentNode.removeChild(componentRootNode); + } + + componentRef.destroy(); + }); + } } // At this point the component has been instantiated, so we move it to the location in the DOM