refactor(ivy): remove directiveRefresh instruction (#22745)

PR Close #22745
This commit is contained in:
Kara Erickson
2018-03-13 11:48:09 -07:00
parent 4ac606b419
commit b1365d1fa8
28 changed files with 157 additions and 313 deletions

View File

@ -67,7 +67,6 @@ export {
s as ɵs,
t as ɵt,
v as ɵv,
r as ɵr,
st as ɵst,
ld as ɵld,
Pp as ɵPp,

View File

@ -97,20 +97,7 @@ function queueDestroyHooks(def: DirectiveDef<any>, tView: TView, i: number): voi
export function executeInitHooks(currentView: LView, tView: TView, creationMode: boolean): void {
if (currentView.lifecycleStage === LifecycleStage.INIT) {
executeHooks(currentView.data, tView.initHooks, tView.checkHooks, creationMode);
currentView.lifecycleStage = LifecycleStage.CONTENT_INIT;
}
}
/**
* Calls all afterContentInit and afterContentChecked hooks for the view, then splices
* out afterContentInit hooks to prep for the next run in update mode.
*
* @param currentView The current view
*/
export function executeContentHooks(currentView: LView, tView: TView, creationMode: boolean): void {
if (currentView.lifecycleStage < LifecycleStage.VIEW_INIT) {
executeHooks(currentView.data, tView.contentHooks, tView.contentCheckHooks, creationMode);
currentView.lifecycleStage = LifecycleStage.VIEW_INIT;
currentView.lifecycleStage = LifecycleStage.AFTER_INIT;
}
}

View File

@ -40,8 +40,6 @@ export {
interpolation8 as i8,
interpolationV as iV,
directiveRefresh as r,
container as C,
containerRefreshStart as cR,
containerRefreshEnd as cr,

View File

@ -22,7 +22,7 @@ import {matchingSelectorIndex} from './node_selector_matcher';
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveType} from './interfaces/definition';
import {RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, ObjectOrientedRenderer3, RendererStyleFlags3, isProceduralRenderer} from './interfaces/renderer';
import {isDifferent, stringify} from './util';
import {executeHooks, executeContentHooks, queueLifecycleHooks, queueInitHooks, executeInitHooks} from './hooks';
import {executeHooks, queueLifecycleHooks, queueInitHooks, executeInitHooks} from './hooks';
import {ViewRef} from './view_ref';
/**
@ -209,10 +209,31 @@ export function leaveView(newView: LView): void {
// Views should be clean and in update mode after being checked, so these bits are cleared
currentView.flags &= ~(LViewFlags.CreationMode | LViewFlags.Dirty);
currentView.lifecycleStage = LifecycleStage.INIT;
currentView.tView.firstTemplatePass = false;
enterView(newView, null);
}
/** Refreshes the views of child components, triggering any init/content hooks existing. */
function refreshChildComponents() {
executeInitAndContentHooks();
// This needs to be set before children are processed to support recursive components
currentView.tView.firstTemplatePass = false;
const components = currentView.tView.components;
if (components != null) {
for (let i = 0; i < components.length; i++) {
componentRefresh(components[i] + 1, components[i]);
}
}
}
function executeInitAndContentHooks(): void {
if (!checkNoChangesMode) {
const tView = currentView.tView;
executeInitHooks(currentView, tView, creationMode);
executeHooks(currentView.data, tView.contentHooks, tView.contentCheckHooks, creationMode);
}
}
export function createLView(
viewId: number, renderer: Renderer3, tView: TView, template: ComponentTemplate<any>| null,
context: any | null, flags: LViewFlags): LView {
@ -376,8 +397,9 @@ export function renderEmbeddedTemplate<T>(
enterView(viewNode.data, viewNode);
template(context, cm);
} finally {
refreshDynamicChildren();
refreshChildComponents();
} finally {
leaveView(currentView !.parent !);
isParent = _isParent;
previousOrParentNode = _previousOrParentNode;
@ -394,10 +416,12 @@ export function renderComponentOrTemplate<T>(
}
if (template) {
template(componentOrContext !, creationMode);
refreshChildComponents();
} else {
executeInitAndContentHooks();
// Element was stored at 0 and directive was stored at 1 in renderComponent
// so to refresh the component, refresh() needs to be called with (1, 0)
directiveRefresh(1, 0);
componentRefresh(1, 0);
}
} finally {
if (rendererFactory.end) {
@ -482,6 +506,7 @@ export function elementStart(
// TODO(mhevery): This assumes that the directives come in correct order, which
// is not guaranteed. Must be refactored to take it into account.
const instance = hostComponentDef.n();
storeComponentIndex(index);
directiveCreate(++index, instance, hostComponentDef, queryName);
initChangeDetectorIfExisting(node.nodeInjector, instance);
}
@ -491,6 +516,13 @@ export function elementStart(
return native;
}
/** Stores index of component so it will be queued for refresh during change detection. */
function storeComponentIndex(index: number): void {
if (currentView.tView.firstTemplatePass) {
(currentView.tView.components || (currentView.tView.components = [])).push(index);
}
}
/** Sets the context for a ChangeDetectorRef to the given instance. */
export function initChangeDetectorIfExisting(injector: LInjector | null, instance: any): void {
if (injector && injector.changeDetectorRef != null) {
@ -565,7 +597,8 @@ export function createTView(): TView {
contentCheckHooks: null,
viewHooks: null,
viewCheckHooks: null,
destroyHooks: null
destroyHooks: null,
components: null
};
}
@ -1250,6 +1283,7 @@ function getOrCreateEmbeddedTView(viewIndex: number, parent: LContainerNode): TV
/** Marks the end of an embedded view. */
export function embeddedViewEnd(): void {
refreshChildComponents();
isParent = false;
const viewNode = previousOrParentNode = currentView.node as LViewNode;
const container = previousOrParentNode.parent as LContainerNode;
@ -1274,7 +1308,7 @@ export function embeddedViewEnd(): void {
/////////////
/**
* Refreshes the directive, triggering init and content hooks.
* Refreshes the directive.
*
* When it is a component, it also enters the component's view and processes it to update bindings,
* queries, etc.
@ -1282,11 +1316,7 @@ export function embeddedViewEnd(): void {
* @param directiveIndex
* @param elementIndex
*/
export function directiveRefresh<T>(directiveIndex: number, elementIndex: number): void {
if (!checkNoChangesMode) {
executeInitHooks(currentView, currentView.tView, creationMode);
executeContentHooks(currentView, currentView.tView, creationMode);
}
export function componentRefresh<T>(directiveIndex: number, elementIndex: number): void {
const template = (tData[directiveIndex] as ComponentDef<T>).template;
if (template != null) {
ngDevMode && assertDataInRange(elementIndex);
@ -1649,8 +1679,9 @@ function detectChangesInternal<T>(hostView: LView, hostNode: LElementNode, compo
if (template != null) {
try {
template(component, creationMode);
} finally {
refreshDynamicChildren();
refreshChildComponents();
} finally {
leaveView(oldView);
}
}

View File

@ -276,6 +276,12 @@ export interface TView {
* Odd indices: Hook function
*/
destroyHooks: HookData|null;
/**
* A list of element indices for child components that will need to be refreshed when the
* current view has finished its check.
*/
components: number[]|null;
}
/**
@ -312,15 +318,14 @@ export interface RootContext {
export type HookData = (number | (() => void))[];
/** Possible values of LView.lifecycleStage, used to determine which hooks to run. */
// TODO: Remove this enum when containerRefresh instructions are removed
export const enum LifecycleStage {
/* Init hooks need to be run, if any. */
INIT = 1,
/* Content hooks need to be run, if any. Init hooks have already run. */
CONTENT_INIT = 2,
/* View hooks need to be run, if any. Any init hooks/content hooks have ran. */
VIEW_INIT = 3
AFTER_INIT = 2,
}
/**