refactor(ivy): move id to TView (#24264)

PR Close #24264
This commit is contained in:
Kara Erickson 2018-06-01 19:28:20 -07:00 committed by Victor Berchet
parent cb65724761
commit 5794506c64
6 changed files with 35 additions and 26 deletions

View File

@ -138,8 +138,8 @@ export function renderComponent<T>(
clean: CLEAN_PROMISE,
};
const rootView: LView = createLView(
-1, rendererFactory.createRenderer(hostNode, componentDef.rendererType),
createTView(null, null), null, rootContext,
rendererFactory.createRenderer(hostNode, componentDef.rendererType),
createTView(-1, null, null), null, rootContext,
componentDef.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways);
rootView.injector = opts.injector || null;

View File

@ -700,7 +700,7 @@ export function getOrCreateTemplateRef<T>(di: LInjector): viewEngine_TemplateRef
const hostTNode = hostNode.tNode;
const hostTView = hostNode.view.tView;
if (!hostTNode.tViews) {
hostTNode.tViews = createTView(hostTView.directiveRegistry, hostTView.pipeRegistry);
hostTNode.tViews = createTView(-1, hostTView.directiveRegistry, hostTView.pipeRegistry);
}
ngDevMode && assertNotNull(hostTNode.tViews, 'TView must be allocated');
di.templateRef = new TemplateRef<any>(

View File

@ -298,11 +298,10 @@ export function executeInitAndContentHooks(): void {
}
export function createLView<T>(
viewId: number, renderer: Renderer3, tView: TView, template: ComponentTemplate<T>| null,
context: T | null, flags: LViewFlags, sanitizer?: Sanitizer | null): LView {
renderer: Renderer3, tView: TView, template: ComponentTemplate<T>| null, context: T | null,
flags: LViewFlags, sanitizer?: Sanitizer | null): LView {
const newView = {
parent: currentView,
id: viewId, // -1 for component views
flags: flags | LViewFlags.CreationMode | LViewFlags.Attached | LViewFlags.RunInit,
node: null !, // until we initialize it in createNode.
data: [],
@ -465,7 +464,7 @@ export function renderTemplate<T>(
host = createLNode(
-1, TNodeType.Element, hostNode, null, null,
createLView(
-1, providedRendererFactory.createRenderer(null, null), tView, null, {},
providedRendererFactory.createRenderer(null, null), tView, null, {},
LViewFlags.CheckAlways, sanitizer));
}
const hostView = host.data !;
@ -497,7 +496,7 @@ export function renderEmbeddedTemplate<T>(
if (viewNode == null) {
const lView = createLView(
-1, renderer, tView, template, context, LViewFlags.CheckAlways, getCurrentSanitizer());
renderer, tView, template, context, LViewFlags.CheckAlways, getCurrentSanitizer());
if (queries) {
lView.queries = queries.createView();
@ -784,14 +783,22 @@ function getOrCreateTView(
// and not on embedded templates.
return template.ngPrivateData ||
(template.ngPrivateData = createTView(directives, pipes) as never);
(template.ngPrivateData = createTView(-1, directives, pipes) as never);
}
/** Creates a TView instance */
/**
* Creates a TView instance
*
* @param viewIndex The viewBlockId for inline views, or -1 if it's a component/dynamic
* @param directives Registry of directives for this view
* @param pipes Registry of pipes for this view
*/
export function createTView(
defs: DirectiveDefListOrFactory | null, pipes: PipeDefListOrFactory | null): TView {
viewIndex: number, directives: DirectiveDefListOrFactory | null,
pipes: PipeDefListOrFactory | null): TView {
ngDevMode && ngDevMode.tView++;
return {
id: viewIndex,
node: null !,
data: [],
childIndex: -1, // Children set in addToViewTree(), if any
@ -808,7 +815,7 @@ export function createTView(
pipeDestroyHooks: null,
hostBindings: null,
components: null,
directiveRegistry: typeof defs === 'function' ? defs() : defs,
directiveRegistry: typeof directives === 'function' ? directives() : directives,
pipeRegistry: typeof pipes === 'function' ? pipes() : pipes,
currentMatches: null
};
@ -875,7 +882,7 @@ export function hostElement(
const node = createLNode(
0, TNodeType.Element, rNode, null, null,
createLView(
-1, renderer, getOrCreateTView(def.template, def.directiveDefs, def.pipeDefs), null, null,
renderer, getOrCreateTView(def.template, def.directiveDefs, def.pipeDefs), null, null,
def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways, sanitizer));
if (firstTemplatePass) {
@ -1324,7 +1331,6 @@ function addComponentLogic<T>(index: number, instance: T, def: ComponentDef<T>):
const hostView = addToViewTree(
currentView, previousOrParentNode.tNode.index as number,
createLView(
-1,
rendererFactory.createRenderer(previousOrParentNode.native as RElement, def.rendererType),
tView, null, null, def.onPush ? LViewFlags.Dirty : LViewFlags.CheckAlways,
getCurrentSanitizer()));
@ -1605,7 +1611,7 @@ function scanForView(
containerNode: LContainerNode, startIdx: number, viewBlockId: number): LViewNode|null {
const views = containerNode.data.views;
for (let i = startIdx; i < views.length; i++) {
const viewAtPositionId = views[i].data.id;
const viewAtPositionId = views[i].data.tView.id;
if (viewAtPositionId === viewBlockId) {
return views[i];
} else if (viewAtPositionId < viewBlockId) {
@ -1642,7 +1648,7 @@ export function embeddedViewStart(viewBlockId: number): RenderFlags {
} else {
// When we create a new LView, we always reset the state of the instructions.
const newView = createLView(
viewBlockId, renderer, getOrCreateEmbeddedTView(viewBlockId, container), null, null,
renderer, getOrCreateEmbeddedTView(viewBlockId, container), null, null,
LViewFlags.CheckAlways, getCurrentSanitizer());
if (lContainer.queries) {
@ -1673,7 +1679,8 @@ function getOrCreateEmbeddedTView(viewIndex: number, parent: LContainerNode): TV
ngDevMode && assertEqual(Array.isArray(containerTViews), true, 'TViews should be in an array');
if (viewIndex >= containerTViews.length || containerTViews[viewIndex] == null) {
const tView = currentView.tView;
containerTViews[viewIndex] = createTView(tView.directiveRegistry, tView.pipeRegistry);
containerTViews[viewIndex] =
createTView(viewIndex, tView.directiveRegistry, tView.pipeRegistry);
}
return containerTViews[viewIndex];
}

View File

@ -49,13 +49,6 @@ export interface LView {
// TODO(kara): Remove when we have parent/child on TNodes
readonly node: LViewNode|LElementNode;
/**
* ID to determine whether this view is the same as the previous view
* in this position. If it's not, we know this view needs to be inserted
* and the one that exists needs to be removed (e.g. if/else statements)
*/
readonly id: number;
/** Renderer to be used for this view. */
readonly renderer: Renderer3;
@ -207,6 +200,15 @@ export interface LViewOrLContainer {
* Stored on the template function as ngPrivateData.
*/
export interface TView {
/**
* ID for inline views to determine whether a view is the same as the previous view
* in a certain position. If it's not, we know the new view needs to be inserted
* and the one that exists needs to be removed (e.g. if/else statements)
*
* If this is -1, then this is a component view or a dynamically created view.
*/
readonly id: number;
/**
* Pointer to the `TNode` that represents the root of the view.
*

View File

@ -426,7 +426,7 @@ function cleanUpView(view: LView): void {
executeOnDestroys(view);
executePipeOnDestroys(view);
// For component views only, the local renderer is destroyed as clean up time.
if (view.id === -1 && isProceduralRenderer(view.renderer)) {
if (view.tView && view.tView.id === -1 && isProceduralRenderer(view.renderer)) {
ngDevMode && ngDevMode.rendererDestroy++;
view.renderer.destroy();
}

View File

@ -1404,7 +1404,7 @@ describe('di', () => {
describe('getOrCreateNodeInjector', () => {
it('should handle initial undefined state', () => {
const contentView =
createLView(-1, null !, createTView(null, null), null, null, LViewFlags.CheckAlways);
createLView(null !, createTView(-1, null, null), null, null, LViewFlags.CheckAlways);
const oldView = enterView(contentView, null !);
try {
const parent = createLNode(0, TNodeType.Element, null, null, null, null);