refactor(upgrade): remove redundant call to appRef.detach()
Once a `ViewRef` is attached to the `ApplicationRef`, destroying the corresponding `ComponentRef` will automatically detach the `ViewRef`.
This commit is contained in:
parent
4e6aa9c2db
commit
29dbc3b67c
@ -115,7 +115,7 @@ export function downgradeComponent(info: {
|
|||||||
facade.createComponent(projectableNodes);
|
facade.createComponent(projectableNodes);
|
||||||
facade.setupInputs(needsNgZone, info.propagateDigest);
|
facade.setupInputs(needsNgZone, info.propagateDigest);
|
||||||
facade.setupOutputs();
|
facade.setupOutputs();
|
||||||
facade.registerCleanup(needsNgZone);
|
facade.registerCleanup();
|
||||||
|
|
||||||
injectorPromise.resolve(facade.getInjector());
|
injectorPromise.resolve(facade.getInjector());
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ export class DowngradeComponentAdapter {
|
|||||||
private componentRef: ComponentRef<any>;
|
private componentRef: ComponentRef<any>;
|
||||||
private component: any;
|
private component: any;
|
||||||
private changeDetector: ChangeDetectorRef;
|
private changeDetector: ChangeDetectorRef;
|
||||||
private appRef: ApplicationRef;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private element: angular.IAugmentedJQuery, private attrs: angular.IAttributes,
|
private element: angular.IAugmentedJQuery, private attrs: angular.IAttributes,
|
||||||
@ -35,7 +34,6 @@ export class DowngradeComponentAdapter {
|
|||||||
private componentFactory: ComponentFactory<any>,
|
private componentFactory: ComponentFactory<any>,
|
||||||
private wrapCallback: <T>(cb: () => T) => () => T) {
|
private wrapCallback: <T>(cb: () => T) => () => T) {
|
||||||
this.componentScope = scope.$new();
|
this.componentScope = scope.$new();
|
||||||
this.appRef = parentInjector.get(ApplicationRef);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compileContents(): Node[][] {
|
compileContents(): Node[][] {
|
||||||
@ -154,7 +152,8 @@ export class DowngradeComponentAdapter {
|
|||||||
|
|
||||||
// Attach the view so that it will be dirty-checked.
|
// Attach the view so that it will be dirty-checked.
|
||||||
if (needsNgZone) {
|
if (needsNgZone) {
|
||||||
this.appRef.attachView(this.componentRef.hostView);
|
const appRef = this.parentInjector.get<ApplicationRef>(ApplicationRef);
|
||||||
|
appRef.attachView(this.componentRef.hostView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +201,7 @@ export class DowngradeComponentAdapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registerCleanup(needsNgZone: boolean) {
|
registerCleanup() {
|
||||||
const destroyComponentRef = this.wrapCallback(() => this.componentRef.destroy());
|
const destroyComponentRef = this.wrapCallback(() => this.componentRef.destroy());
|
||||||
|
|
||||||
this.element.on !('$destroy', () => {
|
this.element.on !('$destroy', () => {
|
||||||
@ -210,9 +209,6 @@ export class DowngradeComponentAdapter {
|
|||||||
this.componentRef.injector.get(TestabilityRegistry)
|
this.componentRef.injector.get(TestabilityRegistry)
|
||||||
.unregisterApplication(this.componentRef.location.nativeElement);
|
.unregisterApplication(this.componentRef.location.nativeElement);
|
||||||
destroyComponentRef();
|
destroyComponentRef();
|
||||||
if (needsNgZone) {
|
|
||||||
this.appRef.detachView(this.componentRef.hostView);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Component, Inject, Injector, Input, NgModule, NgZone, OnChanges, OnDestroy, StaticProvider, destroyPlatform} from '@angular/core';
|
import {ApplicationRef, Component, Inject, Injector, Input, NgModule, NgZone, OnChanges, OnDestroy, StaticProvider, ViewRef, destroyPlatform} from '@angular/core';
|
||||||
import {async, fakeAsync, tick} from '@angular/core/testing';
|
import {async, fakeAsync, tick} from '@angular/core/testing';
|
||||||
import {BrowserModule} from '@angular/platform-browser';
|
import {BrowserModule} from '@angular/platform-browser';
|
||||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||||
@ -306,6 +306,53 @@ export function main() {
|
|||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should detach hostViews from the ApplicationRef once destroyed', async(() => {
|
||||||
|
let ng2Component: Ng2Component;
|
||||||
|
|
||||||
|
@Component({selector: 'ng2', template: ''})
|
||||||
|
class Ng2Component {
|
||||||
|
constructor(public appRef: ApplicationRef) {
|
||||||
|
ng2Component = this;
|
||||||
|
spyOn(appRef, 'attachView').and.callThrough();
|
||||||
|
spyOn(appRef, 'detachView').and.callThrough();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [Ng2Component],
|
||||||
|
entryComponents: [Ng2Component],
|
||||||
|
imports: [BrowserModule],
|
||||||
|
})
|
||||||
|
class Ng2Module {
|
||||||
|
ngDoBootstrap() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bootstrapFn = (extraProviders: StaticProvider[]) =>
|
||||||
|
platformBrowserDynamic(extraProviders).bootstrapModule(Ng2Module);
|
||||||
|
const lazyModuleName = downgradeModule<Ng2Module>(bootstrapFn);
|
||||||
|
const ng1Module =
|
||||||
|
angular.module('ng1', [lazyModuleName])
|
||||||
|
.directive(
|
||||||
|
'ng2', downgradeComponent({component: Ng2Component, propagateDigest}));
|
||||||
|
|
||||||
|
const element = html('<ng2 ng-if="!hideNg2"></ng2>');
|
||||||
|
const $injector = angular.bootstrap(element, [ng1Module.name]);
|
||||||
|
const $rootScope = $injector.get($ROOT_SCOPE) as angular.IRootScopeService;
|
||||||
|
|
||||||
|
// Wait for the module to be bootstrapped.
|
||||||
|
setTimeout(() => {
|
||||||
|
const hostView: ViewRef =
|
||||||
|
(ng2Component.appRef.attachView as jasmine.Spy).calls.mostRecent().args[0];
|
||||||
|
|
||||||
|
expect(hostView.destroyed).toBe(false);
|
||||||
|
|
||||||
|
$rootScope.$apply('hideNg2 = true');
|
||||||
|
|
||||||
|
expect(hostView.destroyed).toBe(true);
|
||||||
|
expect(ng2Component.appRef.detachView).toHaveBeenCalledWith(hostView);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
it('should only retrieve the Angular zone once (and cache it for later use)',
|
it('should only retrieve the Angular zone once (and cache it for later use)',
|
||||||
fakeAsync(() => {
|
fakeAsync(() => {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user