fix(ivy): ngOnDestroy hooks should be called on providers (#27955)

PR Close #27955
This commit is contained in:
Marc Laval
2019-01-07 17:07:39 +01:00
committed by Kara Erickson
parent 996435b79a
commit e775313188
7 changed files with 139 additions and 41 deletions

View File

@ -503,6 +503,10 @@ export function getNodeInjectable(
setTNodeAndViewData(tNode, lData);
try {
value = lData[index] = factory.factory(null, tData, lData, tNode);
const tView = lData[TVIEW];
if (value && factory.isProvider && value.ngOnDestroy) {
(tView.destroyHooks || (tView.destroyHooks = [])).push(index, value.ngOnDestroy);
}
} finally {
if (factory.injectImpl) setInjectImplementation(previousInjectImplementation);
setIncludeViewProviders(previousIncludeViewProviders);

View File

@ -83,7 +83,8 @@ function resolveProvider(
if (isTypeProvider(provider) || !provider.multi) {
// Single provider case: the factory is created and pushed immediately
const factory = new NodeInjectorFactory(providerFactory, isViewProvider, directiveInject);
const factory =
new NodeInjectorFactory(providerFactory, isViewProvider, true, directiveInject);
const existingFactoryIndex = indexOf(
token, tInjectables, isViewProvider ? beginIndex : beginIndex + cptViewProvidersCount,
endIndex);
@ -245,7 +246,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, directiveInject);
const factory = new NodeInjectorFactory(factoryFn, isViewProvider, true, directiveInject);
factory.multi = [];
factory.index = index;
factory.componentProviders = 0;

View File

@ -1732,7 +1732,8 @@ function baseResolveDirective<T>(
tView: TView, viewData: LView, def: DirectiveDef<T>,
directiveFactory: (t: Type<T>| null) => any) {
tView.data.push(def);
const nodeInjectorFactory = new NodeInjectorFactory(directiveFactory, isComponentDef(def), null);
const nodeInjectorFactory =
new NodeInjectorFactory(directiveFactory, isComponentDef(def), false, null);
tView.blueprint.push(nodeInjectorFactory);
viewData.push(nodeInjectorFactory);
}

View File

@ -234,6 +234,10 @@ export class NodeInjectorFactory {
* Set to `true` if the token is declared in `viewProviders` (or if it is component).
*/
isViewProvider: boolean,
/**
* Set to `true` if the token is a provider, and not a directive.
*/
public isProvider: boolean,
injectImplementation: null|(<T>(token: Type<T>|InjectionToken<T>, flags: InjectFlags) => T)) {
this.canSeeViewProviders = isViewProvider;
this.injectImpl = injectImplementation;