refactor(ivy): split up directiveCreate for tree shaking (#22838)

PR Close #22838
This commit is contained in:
Kara Erickson
2018-03-16 20:31:24 -07:00
committed by Misko Hevery
parent 1612985e48
commit e27cfd6236
5 changed files with 67 additions and 43 deletions

View File

@ -12,8 +12,8 @@ import {Injector} from '../di/injector';
import {ComponentRef as viewEngine_ComponentRef} from '../linker/component_factory';
import {assertNotNull} from './assert';
import {queueLifecycleHooks} from './hooks';
import {CLEAN_PROMISE, _getComponentHostLElementNode, createLView, createTView, directiveCreate, enterView, getDirectiveInstance, getRootView, hostElement, initChangeDetectorIfExisting, locateHostElement, renderComponentOrTemplate} from './instructions';
import {queueInitHooks, queueLifecycleHooks} from './hooks';
import {CLEAN_PROMISE, _getComponentHostLElementNode, baseDirectiveCreate, createLView, createTView, enterView, getRootView, hostElement, initChangeDetectorIfExisting, locateHostElement, renderComponentOrTemplate} from './instructions';
import {ComponentDef, ComponentType} from './interfaces/definition';
import {LElementNode} from './interfaces/node';
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
@ -22,6 +22,7 @@ import {stringify} from './util';
import {createViewRef} from './view_ref';
/** Options that control how the component should be bootstrapped. */
export interface CreateComponentOptions {
/** Which renderer factory to use. */
@ -135,7 +136,7 @@ export function renderComponent<T>(
// Create element node at index 0 in data array
elementNode = hostElement(hostNode, componentDef);
// Create directive instance with n() and store at index 1 in data array (el is 0)
component = rootContext.component = directiveCreate(1, componentDef.factory(), componentDef) as T;
component = rootContext.component = baseDirectiveCreate(1, componentDef.factory(), componentDef) as T;
initChangeDetectorIfExisting(elementNode.nodeInjector, component);
} finally {
// We must not use leaveView here because it will set creationMode to false too early,
@ -164,6 +165,9 @@ export function renderComponent<T>(
*/
export function LifecycleHooksFeature(component: any, def: ComponentDef<any>): void {
const elementNode = _getComponentHostLElementNode(component);
// Root component is always created at dir index 1, after host element at 0
queueInitHooks(1, def.onInit, def.doCheck, elementNode.view.tView);
queueLifecycleHooks(elementNode.flags, elementNode.view);
}

View File

@ -1096,6 +1096,34 @@ export function textBinding<T>(index: number, value: T | NO_CHANGE): void {
export function directiveCreate<T>(
index: number, directive: T, directiveDef: DirectiveDef<T>,
localNames?: (string | number)[] | null): T {
const instance = baseDirectiveCreate(index, directive, directiveDef);
ngDevMode && assertNotNull(previousOrParentNode.tNode, 'previousOrParentNode.tNode');
const tNode: TNode|null = previousOrParentNode.tNode !;
if (currentView.tView.firstTemplatePass && localNames) {
tNode.localNames = tNode.localNames ? tNode.localNames.concat(localNames) : localNames;
}
if (tNode && tNode.attrs) {
setInputsFromAttrs<T>(instance, directiveDef !.inputs, tNode);
}
// Init hooks are queued now so ngOnInit is called in host components before
// any projected components.
queueInitHooks(index, directiveDef.onInit, directiveDef.doCheck, currentView.tView);
return instance;
}
/**
* A lighter version of directiveCreate() that is used for the root component
*
* This version does not contain features that we don't already support at root in
* current Angular. Example: local refs and inputs on root component.
*/
export function baseDirectiveCreate<T>(
index: number, directive: T, directiveDef: DirectiveDef<T>): T {
let instance;
ngDevMode &&
assertNull(currentView.bindingStartIndex, 'directives should be created before any bindings');
@ -1117,11 +1145,6 @@ export function directiveCreate<T>(
if (index >= tData.length) {
tData[index] = directiveDef !;
if (localNames) {
ngDevMode && assertNotNull(previousOrParentNode.tNode, 'previousOrParentNode.tNode');
const tNode = previousOrParentNode !.tNode !;
tNode.localNames = tNode.localNames ? tNode.localNames.concat(localNames) : localNames;
}
}
const diPublic = directiveDef !.diPublic;
@ -1135,15 +1158,6 @@ export function directiveCreate<T>(
(previousOrParentNode as LElementNode).native, directiveDef !.attributes as string[]);
}
const tNode: TNode|null = previousOrParentNode.tNode !;
if (tNode && tNode.attrs) {
setInputsFromAttrs<T>(instance, directiveDef !.inputs, tNode);
}
// Init hooks are queued now so ngOnInit is called in host components before
// any projected components.
queueInitHooks(index, directiveDef.onInit, directiveDef.doCheck, currentView.tView);
return instance;
}