fix(upgrade): ensure downgraded components are destroyed in the Angular zone
This commit is contained in:
parent
745b59f49c
commit
4e6aa9c2db
|
@ -203,11 +203,13 @@ export class DowngradeComponentAdapter {
|
||||||
}
|
}
|
||||||
|
|
||||||
registerCleanup(needsNgZone: boolean) {
|
registerCleanup(needsNgZone: boolean) {
|
||||||
|
const destroyComponentRef = this.wrapCallback(() => this.componentRef.destroy());
|
||||||
|
|
||||||
this.element.on !('$destroy', () => {
|
this.element.on !('$destroy', () => {
|
||||||
this.componentScope.$destroy();
|
this.componentScope.$destroy();
|
||||||
this.componentRef.injector.get(TestabilityRegistry)
|
this.componentRef.injector.get(TestabilityRegistry)
|
||||||
.unregisterApplication(this.componentRef.location.nativeElement);
|
.unregisterApplication(this.componentRef.location.nativeElement);
|
||||||
this.componentRef.destroy();
|
destroyComponentRef();
|
||||||
if (needsNgZone) {
|
if (needsNgZone) {
|
||||||
this.appRef.detachView(this.componentRef.hostView);
|
this.appRef.detachView(this.componentRef.hostView);
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ export function main() {
|
||||||
let $compile = undefined as any;
|
let $compile = undefined as any;
|
||||||
let $parse = undefined as any;
|
let $parse = undefined as any;
|
||||||
let componentFactory: ComponentFactory<any>; // testbed
|
let componentFactory: ComponentFactory<any>; // testbed
|
||||||
let wrapCallback = undefined as any;
|
let wrapCallback = (cb: any) => cb;
|
||||||
|
|
||||||
content = `
|
content = `
|
||||||
<h1> new component </h1>
|
<h1> new component </h1>
|
||||||
|
@ -183,7 +183,7 @@ export function main() {
|
||||||
expect(registry.getAllTestabilities().length).toEqual(0);
|
expect(registry.getAllTestabilities().length).toEqual(0);
|
||||||
adapter.createComponent([]);
|
adapter.createComponent([]);
|
||||||
expect(registry.getAllTestabilities().length).toEqual(1);
|
expect(registry.getAllTestabilities().length).toEqual(1);
|
||||||
adapter.registerCleanup(true);
|
adapter.registerCleanup();
|
||||||
element.remove !();
|
element.remove !();
|
||||||
expect(registry.getAllTestabilities().length).toEqual(0);
|
expect(registry.getAllTestabilities().length).toEqual(0);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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, StaticProvider, destroyPlatform} from '@angular/core';
|
import {Component, Inject, Injector, Input, NgModule, NgZone, OnChanges, OnDestroy, StaticProvider, 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';
|
||||||
|
@ -170,6 +170,42 @@ export function main() {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should destroy components inside the Angular zone', async(() => {
|
||||||
|
let destroyedInTheZone = false;
|
||||||
|
|
||||||
|
@Component({selector: 'ng2', template: ''})
|
||||||
|
class Ng2Component implements OnDestroy {
|
||||||
|
ngOnDestroy() { destroyedInTheZone = NgZone.isInAngularZone(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@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(() => {
|
||||||
|
$rootScope.$apply('hideNg2 = true');
|
||||||
|
expect(destroyedInTheZone).toBe(true);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
it('should propagate input changes inside the Angular zone', async(() => {
|
it('should propagate input changes inside the Angular zone', async(() => {
|
||||||
let ng2Component: Ng2Component;
|
let ng2Component: Ng2Component;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue