fix(upgrade): detect async downgrade component changes (#13812)

This commit effectively reverts 7e0f02f96e
as it was an invalid fix for #6385, that created a more significant
bug, which was that changes were not always being detected.

Angular 1 digests should be run inside the ngZone to ensure
that async changes are detected.

We don't know how to fix #6385 without breaking change detection
at this stage. That issue is triggered by async operations, such as
`setTimeout`, being triggered inside scope watcher functions.

One could argue that watcher functions should be pure and not do
work such as triggering async operations. It is possible that the
original use case could be supported by moving the debounce
logic into the watch listener function, which is only called if the
watched value actually changes.

Closes #10660, #12318, #12034

PR Close #13812
This commit is contained in:
Peter Bacon Darwin
2017-01-13 20:19:57 +00:00
committed by Miško Hevery
parent 87316c52db
commit 2250082fd7
2 changed files with 88 additions and 6 deletions

View File

@ -577,10 +577,6 @@ export class UpgradeAdapter {
})
.then((ref: NgModuleRef<any>) => {
this.moduleRef = ref;
let subscription = this.ngZone.onMicrotaskEmpty.subscribe({
next: (_: any) => this.ngZone.runOutsideAngular(() => rootScope.$evalAsync())
});
rootScope.$on('$destroy', () => { subscription.unsubscribe(); });
this.ngZone.run(() => {
if (rootScopePrototype) {
rootScopePrototype.$apply = original$applyFn; // restore original $apply
@ -591,7 +587,12 @@ export class UpgradeAdapter {
}
});
})
.then(() => this.ng2BootstrapDeferred.resolve(ng1Injector), onError);
.then(() => this.ng2BootstrapDeferred.resolve(ng1Injector), onError)
.then(() => {
let subscription =
this.ngZone.onMicrotaskEmpty.subscribe({next: () => rootScope.$digest()});
rootScope.$on('$destroy', () => { subscription.unsubscribe(); });
});
})
.catch((e) => this.ng2BootstrapDeferred.reject(e));
}