refactor(ivy): remove type
from DirectiveDef
(#21374)
This change makes the code cleaner for the user. It does mean a little bit more work for us since we have to patch the `type` back into the `DirectiveDef`. However since the patching happens only once on startup it should not be significant. PR Close #21374
This commit is contained in:
@ -13,13 +13,14 @@ import {ComponentRef as viewEngine_ComponentRef} from '../linker/component_facto
|
||||
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef} from '../linker/view_ref';
|
||||
|
||||
import {assertNotNull} from './assert';
|
||||
import {NG_HOST_SYMBOL, createError, createLView, directive, enterView, hostElement, leaveView, locateHostElement, renderComponentOrTemplate, directiveCreate} from './instructions';
|
||||
import {ComponentDef, ComponentType} from './interfaces/definition';
|
||||
import {NG_HOST_SYMBOL, createError, createLView, directive, directiveCreate, enterView, hostElement, leaveView, locateHostElement, renderComponentOrTemplate} from './instructions';
|
||||
import {ComponentDef, ComponentType, TypedComponentDef} from './interfaces/definition';
|
||||
import {LElementNode} from './interfaces/node';
|
||||
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
||||
import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
|
||||
import {notImplemented, stringify} from './util';
|
||||
|
||||
|
||||
|
||||
/** Options that control how the component should be bootstrapped. */
|
||||
export interface CreateComponentOptions {
|
||||
/** Which renderer factory to use. */
|
||||
@ -165,7 +166,8 @@ export const NULL_INJECTOR: Injector = {
|
||||
export function renderComponent<T>(
|
||||
componentType: ComponentType<T>, opts: CreateComponentOptions = {}): T {
|
||||
const rendererFactory = opts.rendererFactory || domRendererFactory3;
|
||||
const componentDef = componentType.ngComponentDef;
|
||||
const componentDef = componentType.ngComponentDef as TypedComponentDef<T>;
|
||||
if (componentDef.type != componentType) componentDef.type = componentType;
|
||||
let component: T;
|
||||
const hostNode = locateHostElement(rendererFactory, opts.host || componentDef.tag);
|
||||
const oldView = enterView(
|
||||
|
@ -32,7 +32,6 @@ import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs} from './
|
||||
*/
|
||||
export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): ComponentDef<T> {
|
||||
const def = <ComponentDef<any>>{
|
||||
type: componentDefinition.type,
|
||||
diPublic: null,
|
||||
n: componentDefinition.factory,
|
||||
tag: (componentDefinition as ComponentDefArgs<T>).tag || null !,
|
||||
|
@ -17,7 +17,7 @@ import {ViewContainerRef as viewEngine_ViewContainerRef} from '../linker/view_co
|
||||
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef, ViewRef as viewEngine_ViewRef} from '../linker/view_ref';
|
||||
import {Type} from '../type';
|
||||
|
||||
import {ComponentTemplate, DirectiveDef} from './interfaces/definition';
|
||||
import {ComponentTemplate, DirectiveDef, TypedDirectiveDef} from './interfaces/definition';
|
||||
import {LInjector} from './interfaces/injector';
|
||||
import {LContainerNode, LElementNode, LNodeFlags} from './interfaces/node';
|
||||
import {assertNodeType} from './node_assert';
|
||||
@ -147,7 +147,7 @@ function createInjectionError(text: string, token: any) {
|
||||
* @param di The node injector in which a directive will be added
|
||||
* @param def The definition of the directive to be made public
|
||||
*/
|
||||
export function diPublicInInjector(di: LInjector, def: DirectiveDef<any>): void {
|
||||
export function diPublicInInjector(di: LInjector, def: TypedDirectiveDef<any>): void {
|
||||
bloomAdd(di, def.type);
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ export function getOrCreateInjectable<T>(di: LInjector, token: Type<T>, flags?:
|
||||
for (let i = start, ii = start + size; i < ii; i++) {
|
||||
// Get the definition for the directive at this index and, if it is injectable (diPublic),
|
||||
// and matches the given token, return the directive instance.
|
||||
const directiveDef = ngStaticData[i] as DirectiveDef<any>;
|
||||
const directiveDef = ngStaticData[i] as TypedDirectiveDef<any>;
|
||||
if (directiveDef.diPublic && directiveDef.type == token) {
|
||||
return node.view.data[i];
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ import {LContainerNode, LElementNode, LNode, LNodeFlags, LProjectionNode, LTextN
|
||||
import {assertNodeType} from './node_assert';
|
||||
import {appendChild, insertChild, insertView, processProjectedNode, removeView} from './node_manipulation';
|
||||
import {isNodeMatchingSelector} from './node_selector_matcher';
|
||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveType} from './interfaces/definition';
|
||||
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveType, TypedDirectiveDef, TypedComponentDef} from './interfaces/definition';
|
||||
import {InjectFlags, diPublicInInjector, getOrCreateNodeInjectorForNode, getOrCreateElementRef, getOrCreateTemplateRef, getOrCreateContainerRef, getOrCreateInjectable} from './di';
|
||||
import {QueryList, LQuery_} from './query';
|
||||
import {RComment, RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, ObjectOrientedRenderer3, RendererStyleFlags3} from './interfaces/renderer';
|
||||
@ -343,7 +343,7 @@ export function getOrCreateNodeInjector(): LInjector {
|
||||
*
|
||||
* @param def The definition of the directive to be made public
|
||||
*/
|
||||
export function diPublic(def: DirectiveDef<any>): void {
|
||||
export function diPublic(def: TypedDirectiveDef<any>): void {
|
||||
diPublicInInjector(getOrCreateNodeInjector(), def);
|
||||
}
|
||||
|
||||
@ -475,6 +475,8 @@ export function elementStart(
|
||||
if (hostComponentDef) {
|
||||
// TODO(mhevery): This assumes that the directives come in correct order, which
|
||||
// is not guaranteed. Must be refactored to take it into account.
|
||||
(hostComponentDef as TypedComponentDef<any>).type =
|
||||
nameOrComponentType as ComponentType<any>;
|
||||
directiveCreate(++index, hostComponentDef.n(), hostComponentDef, queryName);
|
||||
}
|
||||
hack_declareDirectives(index, directiveTypes, localRefs);
|
||||
@ -500,7 +502,9 @@ function hack_declareDirectives(
|
||||
// template
|
||||
// code for slight startup(first run) performance. (No impact on subsequent runs)
|
||||
// TODO(misko): refactor this to store the `DirectiveDef` in `TView.data`.
|
||||
const directiveDef = directiveTypes[i].ngDirectiveDef;
|
||||
const directiveType = directiveTypes[i];
|
||||
const directiveDef = directiveType.ngDirectiveDef;
|
||||
(directiveDef as TypedDirectiveDef<any>).type = directiveType;
|
||||
directiveCreate(
|
||||
++index, directiveDef.n(), directiveDef, hack_findQueryName(directiveDef, localRefs));
|
||||
}
|
||||
@ -945,8 +949,7 @@ export function directiveCreate<T>(
|
||||
if (index >= ngStaticData.length) {
|
||||
ngStaticData[index] = directiveDef !;
|
||||
if (queryName) {
|
||||
ngDevMode &&
|
||||
assertNotNull(previousOrParentNode.tNode, 'previousOrParentNode.staticData');
|
||||
ngDevMode && assertNotNull(previousOrParentNode.tNode, 'previousOrParentNode.staticData');
|
||||
const nodeStaticData = previousOrParentNode !.tNode !;
|
||||
(nodeStaticData.localNames || (nodeStaticData.localNames = [])).push(queryName, index);
|
||||
}
|
||||
|
@ -28,11 +28,6 @@ export const enum DirectiveDefFlags {ContentQuery = 0b10}
|
||||
* `DirectiveDef` is a compiled version of the Directive used by the renderer instructions.
|
||||
*/
|
||||
export interface DirectiveDef<T> {
|
||||
/**
|
||||
* Token representing the directive. Used by DI.
|
||||
*/
|
||||
type: Type<T>;
|
||||
|
||||
/** Function that makes a directive public to the DI system. */
|
||||
diPublic: ((def: DirectiveDef<any>) => void)|null;
|
||||
|
||||
@ -41,26 +36,26 @@ export interface DirectiveDef<T> {
|
||||
*
|
||||
* The key is minified property name whereas the value is the original unminified name.
|
||||
*/
|
||||
inputs: {[P in keyof T]: P};
|
||||
readonly inputs: {[P in keyof T]: P};
|
||||
|
||||
/**
|
||||
* List of outputs which are part of the components public API.
|
||||
*
|
||||
* The key is minified property name whereas the value is the original unminified name.=
|
||||
*/
|
||||
outputs: {[P in keyof T]: P};
|
||||
readonly outputs: {[P in keyof T]: P};
|
||||
|
||||
/**
|
||||
* List of methods which are part of the components public API.
|
||||
*
|
||||
* The key is minified property name whereas the value is the original unminified name.
|
||||
*/
|
||||
methods: {[P in keyof T]: P};
|
||||
readonly methods: {[P in keyof T]: P};
|
||||
|
||||
/**
|
||||
* Name under which the directive is exported (for use with local references in template)
|
||||
*/
|
||||
exportAs: string|null;
|
||||
readonly exportAs: string|null;
|
||||
|
||||
/**
|
||||
* factory function used to create a new directive instance.
|
||||
@ -111,25 +106,34 @@ export interface ComponentDef<T> extends DirectiveDef<T> {
|
||||
*
|
||||
* NOTE: only used with component directives.
|
||||
*/
|
||||
tag: string;
|
||||
readonly tag: string;
|
||||
|
||||
/**
|
||||
* The View template of the component.
|
||||
*
|
||||
* NOTE: only used with component directives.
|
||||
*/
|
||||
template: ComponentTemplate<T>;
|
||||
readonly template: ComponentTemplate<T>;
|
||||
|
||||
/**
|
||||
* Renderer type data of the component.
|
||||
*
|
||||
* NOTE: only used with component directives.
|
||||
*/
|
||||
rendererType: RendererType2|null;
|
||||
readonly rendererType: RendererType2|null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Private: do not export
|
||||
*/
|
||||
export interface TypedDirectiveDef<T> extends DirectiveDef<T> { type: DirectiveType<T>; }
|
||||
|
||||
/**
|
||||
* Private: do not export
|
||||
*/
|
||||
export interface TypedComponentDef<T> extends ComponentDef<T> { type: ComponentType<T>; }
|
||||
|
||||
export interface DirectiveDefArgs<T> {
|
||||
type: Type<T>;
|
||||
factory: () => T;
|
||||
refresh?: (directiveIndex: number, elementIndex: number) => void;
|
||||
inputs?: {[P in keyof T]?: string};
|
||||
|
@ -17,13 +17,14 @@ import {Type} from '../type';
|
||||
|
||||
import {assertNotNull} from './assert';
|
||||
import {getOrCreateContainerRef, getOrCreateElementRef, getOrCreateNodeInjectorForNode, getOrCreateTemplateRef} from './di';
|
||||
import {DirectiveDef} from './interfaces/definition';
|
||||
import {DirectiveDef, TypedDirectiveDef} from './interfaces/definition';
|
||||
import {LInjector} from './interfaces/injector';
|
||||
import {LContainerNode, LElementNode, LNode, LNodeFlags, LViewNode, TNode} from './interfaces/node';
|
||||
import {LQuery, QueryReadType} from './interfaces/query';
|
||||
import {assertNodeOfPossibleTypes} from './node_assert';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A predicate which determines if a given element/directive should be included in the query
|
||||
*/
|
||||
@ -142,7 +143,7 @@ function geIdxOfMatchingDirective(node: LNode, type: Type<any>): number|null {
|
||||
for (let i = flags >> LNodeFlags.INDX_SHIFT,
|
||||
ii = i + ((flags & LNodeFlags.SIZE_MASK) >> LNodeFlags.SIZE_SHIFT);
|
||||
i < ii; i++) {
|
||||
const def = ngStaticData[i] as DirectiveDef<any>;
|
||||
const def = ngStaticData[i] as TypedDirectiveDef<any>;
|
||||
if (def.diPublic && def.type === type) {
|
||||
return i;
|
||||
}
|
||||
|
Reference in New Issue
Block a user