refactor(ivy): add TView and TContainer (#21463)

PR Close #21463
This commit is contained in:
Kara Erickson
2018-01-10 18:19:16 -08:00
committed by Alex Eagle
parent 3bcc0e6f76
commit efe545a878
11 changed files with 128 additions and 108 deletions

View File

@ -8,7 +8,7 @@
import {ComponentTemplate} from './definition';
import {LElementNode, LViewNode} from './node';
import {LView} from './view';
import {LView, TView} from './view';
/** The state associated with an LContainer */
@ -68,6 +68,24 @@ export interface LContainer {
readonly template: ComponentTemplate<any>|null;
}
/**
* The static equivalent of LContainer, used in TContainerNode.
*
* The container needs to store static data for each of its embedded views
* (TViews). Otherwise, nodes in embedded views with the same index as nodes
* in their parent views will overwrite each other, as they are in
* the same template.
*
* Each index in this array corresponds to the static data for a certain
* view. So if you had V(0) and V(1) in a container, you might have:
*
* [
* [{tagName: 'div', attrs: ...}, null], // V(0) TView
* [{tagName: 'button', attrs ...}, null] // V(1) TView
* ]
*/
export type TContainer = TView[];
// Note: This hack is necessary so we don't erroneously get a circular dependency
// failure based on types.
export const unusedValueExportToPlacateAjd = 1;

View File

@ -14,7 +14,7 @@ import {resolveRendererType2} from '../../view/util';
* Definition of what a template rendering function should look like.
*/
export type ComponentTemplate<T> = {
(ctx: T, creationMode: boolean): void; ngStaticData?: never;
(ctx: T, creationMode: boolean): void; ngPrivateData?: never;
};
export type EmbeddedTemplate<T> = (ctx: T) => void;

View File

@ -6,13 +6,13 @@
* found in the LICENSE file at https://angular.io/license
*/
import {LContainer} from './container';
import {LContainer, TContainer} from './container';
import {DirectiveDef} from './definition';
import {LInjector} from './injector';
import {LProjection} from './projection';
import {LQuery} from './query';
import {RComment, RElement, RText} from './renderer';
import {LView} from './view';
import {LView, TData, TView} from './view';
/**
@ -198,10 +198,6 @@ export interface LProjectionNode extends LNode {
readonly parent: LElementNode|LViewNode;
}
/** The type of the global ngStaticData array. */
export type NgStaticData = (TNode | DirectiveDef<any>| null)[];
/**
* LNode binding data (flyweight) for a particular node that is shared between all templates
* of a specific type.
@ -263,28 +259,21 @@ export interface TNode {
outputs: PropertyAliases|null|undefined;
/**
* The static data equivalent of LNode.data.
*
* If this TNode corresponds to an LContainerNode, the container will
* need to have nested static data for each of its embedded views.
* Otherwise, nodes in embedded views with the same index as nodes
* in their parent views will overwrite each other, as they are in
* the same template.
* need to store separate static data for each of its views (TContainer).
*
* Each index in this array corresponds to the static data for a certain
* view. So if you had V(0) and V(1) in a container, you might have:
*
* [
* [{tagName: 'div', attrs: ...}, null], // V(0) ngData
* [{tagName: 'button', attrs ...}, null] // V(1) ngData
* ]
* If this TNode corresponds to an LElementNode, data will be null.
*/
containerStatic: (TNode|null)[][]|null;
data: TContainer|null;
}
/** Static data for an LElementNode */
export interface TElementNode extends TNode { containerStatic: null; }
/** Static data for an LElementNode */
export interface TElementNode extends TNode { data: null; }
/** Static data for an LContainerNode */
export interface TContainerNode extends TNode { containerStatic: (TNode|null)[][]; }
export interface TContainerNode extends TNode { data: TContainer; }
/**
* This mapping is necessary so we can set input properties and output listeners

View File

@ -129,19 +129,15 @@ export interface LView {
* appear in the template, starting with `bindingStartIndex`.
* We use `bindingIndex` to internally keep track of which binding
* is currently active.
*
* NOTE: We also use data == null as a marker for creationMode. We
* do this by creating ViewState in incomplete state with nodes == null
* and we initialize it on first run.
*/
readonly data: any[];
/**
* The static data array for the current view. We need a reference to this so we
* can easily walk up the node tree in DI and get the ngStaticData array associated
* with a node (where the directive defs are stored).
* The static data for this view. We need a reference to this so we can easily walk up the
* node tree in DI and get the TView.data array associated with a node (where the
* directive defs are stored).
*/
ngStaticData: (TNode|DirectiveDef<any>|null)[];
tView: TView;
}
/** Interface necessary to work with view tree traversal */
@ -152,6 +148,24 @@ export interface LViewOrLContainer {
parent: LView|null;
}
/**
* The static data for an LView (shared between all templates of a
* given type).
*
* Stored on the template function as ngPrivateData.
*/
export interface TView { data: TData; }
/**
* Static data that corresponds to the instance-specific data array on an LView.
*
* Each node's static data is stored in tData at the same index that it's stored
* in the data array. Each directive's definition is stored here at the same index
* as its directive instance in the data array. Any nodes that do not have static
* data store a null value in tData to avoid a sparse array.
*/
export type TData = (TNode | DirectiveDef<any>| null)[];
// Note: This hack is necessary so we don't erroneously get a circular dependency
// failure based on types.
export const unusedValueExportToPlacateAjd = 1;