feat(ivy): support injecting ChangeDetectorRef (#22469)

PR Close #22469
This commit is contained in:
Kara Erickson
2018-02-26 16:58:15 -08:00
committed by Alex Eagle
parent aabe16c08c
commit 9eaf1bbe67
9 changed files with 491 additions and 123 deletions

View File

@ -10,6 +10,7 @@ import './ng_dev_mode';
import {assertEqual, assertLessThan, assertNotEqual, assertNotNull, assertNull, assertSame} from './assert';
import {LContainer, TContainer} from './interfaces/container';
import {LInjector} from './interfaces/injector';
import {CssSelector, LProjection} from './interfaces/projection';
import {LQueries} from './interfaces/query';
import {LView, LViewFlags, LifecycleStage, RootContext, TData, TView} from './interfaces/view';
@ -22,6 +23,7 @@ import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveT
import {RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, RendererStyleFlags3, isProceduralRenderer} from './interfaces/renderer';
import {isDifferent, stringify} from './util';
import {executeHooks, executeContentHooks, queueLifecycleHooks, queueInitHooks, executeInitHooks} from './hooks';
import {ViewRef} from './view_ref';
/**
* Directive (D) sets a property on all component instances using this constant as a key and the
@ -465,7 +467,9 @@ export function elementStart(
if (hostComponentDef) {
// TODO(mhevery): This assumes that the directives come in correct order, which
// is not guaranteed. Must be refactored to take it into account.
directiveCreate(++index, hostComponentDef.n(), hostComponentDef, queryName);
const instance = hostComponentDef.n();
directiveCreate(++index, instance, hostComponentDef, queryName);
initChangeDetectorIfExisting(node.nodeInjector, instance);
}
hack_declareDirectives(index, directiveTypes, localRefs);
}
@ -473,6 +477,13 @@ export function elementStart(
return native;
}
/** Sets the context for a ChangeDetectorRef to the given instance. */
export function initChangeDetectorIfExisting(injector: LInjector | null, instance: any): void {
if (injector && injector.changeDetectorRef != null) {
(injector.changeDetectorRef as ViewRef<any>)._setComponentContext(instance);
}
}
/**
* This function instantiates a directive with a correct queryName. It is a hack since we should
* compute the query value only once and store it with the template (rather than on each invocation)
@ -589,10 +600,12 @@ export function locateHostElement(
*
* @param rNode Render host element.
* @param def ComponentDef
*
* @returns LElementNode created
*/
export function hostElement(rNode: RElement | null, def: ComponentDef<any>) {
export function hostElement(rNode: RElement | null, def: ComponentDef<any>): LElementNode {
resetApplicationState();
createLNode(
return createLNode(
0, LNodeFlags.Element, rNode, createLView(
-1, renderer, getOrCreateTView(def.template), null, null,
def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways));