fix(ivy): component destroy hook called twice when configured as provider (#28470)
Fixes the `ngOnDestroy` hook on a component or directive being called twice, if the type is also registered as a provider. This PR resolves FW-1010. PR Close #28470
This commit is contained in:

committed by
Igor Minar

parent
0ea216b993
commit
e1aaa7ec48
@ -8,8 +8,8 @@
|
||||
|
||||
|
||||
import {resolveForwardRef} from '../di/forward_ref';
|
||||
import {Provider} from '../di/interface/provider';
|
||||
import {isTypeProvider, providerToFactory} from '../di/r3_injector';
|
||||
import {ClassProvider, Provider} from '../di/interface/provider';
|
||||
import {isClassProvider, isTypeProvider, providerToFactory} from '../di/r3_injector';
|
||||
|
||||
import {DirectiveDef} from '.';
|
||||
import {diPublicInInjector, getNodeInjectable, getOrCreateNodeInjectorForNode} from './di';
|
||||
@ -81,10 +81,19 @@ function resolveProvider(
|
||||
const cptViewProvidersCount =
|
||||
tNode.providerIndexes >> TNodeProviderIndexes.CptViewProvidersCountShift;
|
||||
|
||||
if (isClassProvider(provider) || isTypeProvider(provider)) {
|
||||
const prototype = ((provider as ClassProvider).useClass || provider).prototype;
|
||||
const ngOnDestroy = prototype.ngOnDestroy;
|
||||
|
||||
if (ngOnDestroy) {
|
||||
const tView = lView[TVIEW];
|
||||
(tView.destroyHooks || (tView.destroyHooks = [])).push(tInjectables.length, ngOnDestroy);
|
||||
}
|
||||
}
|
||||
|
||||
if (isTypeProvider(provider) || !provider.multi) {
|
||||
// Single provider case: the factory is created and pushed immediately
|
||||
const factory =
|
||||
new NodeInjectorFactory(providerFactory, isViewProvider, true, directiveInject);
|
||||
const factory = new NodeInjectorFactory(providerFactory, isViewProvider, directiveInject);
|
||||
const existingFactoryIndex = indexOf(
|
||||
token, tInjectables, isViewProvider ? beginIndex : beginIndex + cptViewProvidersCount,
|
||||
endIndex);
|
||||
@ -246,7 +255,7 @@ function multiFactory(
|
||||
this: NodeInjectorFactory, _: null, tData: TData, lData: LView, tNode: TElementNode) => any,
|
||||
index: number, isViewProvider: boolean, isComponent: boolean,
|
||||
f: () => any): NodeInjectorFactory {
|
||||
const factory = new NodeInjectorFactory(factoryFn, isViewProvider, true, directiveInject);
|
||||
const factory = new NodeInjectorFactory(factoryFn, isViewProvider, directiveInject);
|
||||
factory.multi = [];
|
||||
factory.index = index;
|
||||
factory.componentProviders = 0;
|
||||
|
Reference in New Issue
Block a user