fix(ivy): instantiate dirs in correct order (#23178)

PR Close #23178
This commit is contained in:
Kara Erickson
2018-04-04 21:21:12 -07:00
committed by Igor Minar
parent d80e9304c6
commit 628303d2cb
8 changed files with 613 additions and 145 deletions

View File

@ -19,7 +19,7 @@ import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, ViewRef as viewEngine_Vie
import {Type} from '../type';
import {assertLessThan, assertNotNull} from './assert';
import {addToViewTree, assertPreviousIsParent, createLContainer, createLNodeObject, getDirectiveInstance, getPreviousOrParentNode, getRenderer, isComponent, renderEmbeddedTemplate} from './instructions';
import {addToViewTree, assertPreviousIsParent, createLContainer, createLNodeObject, getDirectiveInstance, getPreviousOrParentNode, getRenderer, isComponent, renderEmbeddedTemplate, resolveDirective} from './instructions';
import {ComponentTemplate, DirectiveDef} from './interfaces/definition';
import {LInjector} from './interfaces/injector';
import {LContainerNode, LElementNode, LNode, LNodeType, LViewNode, TNodeFlags} from './interfaces/node';
@ -404,8 +404,15 @@ export function getOrCreateInjectable<T>(
}
}
// If we *didn't* find the directive for the token from the candidate injector, we had a false
// positive. Traverse up the tree and continue.
// If we *didn't* find the directive for the token and we are searching the current node's
// injector, it's possible the directive is on this node and hasn't been created yet.
let instance: T|null;
if (injector === di && (instance = searchMatchesQueuedForCreation<T>(node, token))) {
return instance;
}
// The def wasn't found anywhere on this node, so it might be a false positive.
// Traverse up the tree and continue searching.
injector = injector.parent;
}
}
@ -415,6 +422,19 @@ export function getOrCreateInjectable<T>(
throw createInjectionError('Not found', token);
}
function searchMatchesQueuedForCreation<T>(node: LNode, token: any): T|null {
const matches = node.view.tView.currentMatches;
if (matches) {
for (let i = 0; i < matches.length; i += 2) {
const def = matches[i] as DirectiveDef<any>;
if (def.type === token) {
return resolveDirective(def, i + 1, matches, node.view.tView);
}
}
}
return null;
}
/**
* Given a directive type, this function returns the bit in an injector's bloom filter
* that should be used to determine whether or not the directive is present.