Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(ivy): remove directiveRefresh instruction #22745

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 1 addition & 3 deletions modules/benchmarks/src/tree/render3/tree.ts
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {ɵC as C, ɵE as E, ɵT as T, ɵV as V, ɵb as b, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as _detectChanges, ɵe as e, ɵi1 as i1, ɵp as p, ɵr as r, ɵs as s, ɵt as t, ɵv as v} from '@angular/core';
import {ɵC as C, ɵE as E, ɵT as T, ɵV as V, ɵb as b, ɵcR as cR, ɵcr as cr, ɵdefineComponent as defineComponent, ɵdetectChanges as _detectChanges, ɵe as e, ɵi1 as i1, ɵp as p, ɵs as s, ɵt as t, ɵv as v} from '@angular/core';
import {ComponentDef} from '@angular/core/src/render3/interfaces/definition';

import {TreeNode, buildTree, emptyTree} from '../util';
Expand Down Expand Up @@ -59,7 +59,6 @@ export class TreeComponent {
}
p(0, 'data', b(ctx.data.left));
TreeComponent.ngComponentDef.h(1, 0);
r(1, 0);
}
v();
}
Expand All @@ -76,7 +75,6 @@ export class TreeComponent {
}
p(0, 'data', b(ctx.data.right));
TreeComponent.ngComponentDef.h(1, 0);
r(1, 0);
}
v();
}
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/core_render3_private_export.ts
Expand Up @@ -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,
Expand Down
15 changes: 1 addition & 14 deletions packages/core/src/render3/hooks.ts
Expand Up @@ -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;
}
}

Expand Down
2 changes: 0 additions & 2 deletions packages/core/src/render3/index.ts
Expand Up @@ -40,8 +40,6 @@ export {
interpolation8 as i8,
interpolationV as iV,

directiveRefresh as r,

container as C,
containerRefreshStart as cR,
containerRefreshEnd as cr,
Expand Down
55 changes: 43 additions & 12 deletions packages/core/src/render3/instructions.ts
Expand Up @@ -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';

/**
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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);
}
Expand All @@ -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) {
Expand Down Expand Up @@ -565,7 +597,8 @@ export function createTView(): TView {
contentCheckHooks: null,
viewHooks: null,
viewCheckHooks: null,
destroyHooks: null
destroyHooks: null,
components: null
};
}

Expand Down Expand Up @@ -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;
Expand All @@ -1274,19 +1308,15 @@ 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.
*
* @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);
Expand Down Expand Up @@ -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);
}
}
Expand Down
13 changes: 9 additions & 4 deletions packages/core/src/render3/interfaces/view.ts
Expand Up @@ -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;
}

/**
Expand Down Expand Up @@ -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,
}

/**
Expand Down
Expand Up @@ -56,6 +56,9 @@
{
"name": "checkNoChangesMode"
},
{
"name": "componentRefresh"
},
{
"name": "createLNode"
},
Expand All @@ -77,20 +80,17 @@
{
"name": "directiveCreate"
},
{
"name": "directiveRefresh"
},
{
"name": "domRendererFactory3"
},
{
"name": "enterView"
},
{
"name": "executeContentHooks"
"name": "executeHooks"
},
{
"name": "executeHooks"
"name": "executeInitAndContentHooks"
},
{
"name": "executeInitHooks"
Expand Down Expand Up @@ -158,6 +158,9 @@
{
"name": "queueInitHooks"
},
{
"name": "refreshChildComponents"
},
{
"name": "refreshDynamicChildren"
},
Expand Down