refactor(ivy): add type and hooks to directive def (#21650)

PR Close #21650
This commit is contained in:
Kara Erickson 2018-01-22 15:27:21 -08:00 committed by Misko Hevery
parent 97b928053d
commit 98174758ad
20 changed files with 196 additions and 77 deletions

View File

@ -36,6 +36,7 @@ export class TreeComponent {
/** @nocollapse */ /** @nocollapse */
static ngComponentDef: ComponentDef<TreeComponent> = defineComponent({ static ngComponentDef: ComponentDef<TreeComponent> = defineComponent({
type: TreeComponent,
tag: 'tree', tag: 'tree',
template: function(ctx: TreeComponent, cm: boolean) { template: function(ctx: TreeComponent, cm: boolean) {
if (cm) { if (cm) {
@ -92,6 +93,7 @@ export class TreeFunction {
/** @nocollapse */ /** @nocollapse */
static ngComponentDef: ComponentDef<TreeFunction> = defineComponent({ static ngComponentDef: ComponentDef<TreeFunction> = defineComponent({
type: TreeFunction,
tag: 'tree', tag: 'tree',
template: function(ctx: TreeFunction, cm: boolean) { template: function(ctx: TreeFunction, cm: boolean) {
// bit of a hack // bit of a hack

View File

@ -13,8 +13,9 @@ import {ComponentRef as viewEngine_ComponentRef} from '../linker/component_facto
import {EmbeddedViewRef as viewEngine_EmbeddedViewRef} from '../linker/view_ref'; import {EmbeddedViewRef as viewEngine_EmbeddedViewRef} from '../linker/view_ref';
import {assertNotNull} from './assert'; import {assertNotNull} from './assert';
import {NG_HOST_SYMBOL, createError, createLView, directiveCreate, enterView, hostElement, leaveView, locateHostElement, renderComponentOrTemplate} from './instructions'; import {NG_HOST_SYMBOL, createError, createLView, directiveCreate, enterView, hostElement, leaveView, locateHostElement, renderComponentOrTemplate} from './instructions';
import {ComponentDef, ComponentType, TypedComponentDef} from './interfaces/definition'; import {ComponentDef, ComponentType} from './interfaces/definition';
import {LElementNode} from './interfaces/node'; import {LElementNode} from './interfaces/node';
import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer'; import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
import {notImplemented, stringify} from './util'; import {notImplemented, stringify} from './util';
@ -166,7 +167,7 @@ export const NULL_INJECTOR: Injector = {
export function renderComponent<T>( export function renderComponent<T>(
componentType: ComponentType<T>, opts: CreateComponentOptions = {}): T { componentType: ComponentType<T>, opts: CreateComponentOptions = {}): T {
const rendererFactory = opts.rendererFactory || domRendererFactory3; const rendererFactory = opts.rendererFactory || domRendererFactory3;
const componentDef = componentType.ngComponentDef as TypedComponentDef<T>; const componentDef = componentType.ngComponentDef as ComponentDef<T>;
if (componentDef.type != componentType) componentDef.type = componentType; if (componentDef.type != componentType) componentDef.type = componentType;
let component: T; let component: T;
const hostNode = locateHostElement(rendererFactory, opts.host || componentDef.tag); const hostNode = locateHostElement(rendererFactory, opts.host || componentDef.tag);

View File

@ -14,7 +14,7 @@ import {resolveRendererType2} from '../view/util';
import {diPublic} from './di'; import {diPublic} from './di';
import {componentRefresh} from './instructions'; import {componentRefresh} from './instructions';
import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs, TypedDirectiveDef} from './interfaces/definition'; import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs, LifecycleHooksMap} from './interfaces/definition';
@ -35,6 +35,7 @@ import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs, TypedDir
*/ */
export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): ComponentDef<T> { export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): ComponentDef<T> {
const def = <ComponentDef<any>>{ const def = <ComponentDef<any>>{
type: componentDefinition.type,
diPublic: null, diPublic: null,
n: componentDefinition.factory, n: componentDefinition.factory,
tag: (componentDefinition as ComponentDefArgs<T>).tag || null !, tag: (componentDefinition as ComponentDefArgs<T>).tag || null !,
@ -50,6 +51,7 @@ export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): Co
methods: invertObject(componentDefinition.methods), methods: invertObject(componentDefinition.methods),
rendererType: resolveRendererType2(componentDefinition.rendererType) || null, rendererType: resolveRendererType2(componentDefinition.rendererType) || null,
exportAs: componentDefinition.exportAs, exportAs: componentDefinition.exportAs,
lifecycleHooks: getLifecyleHooksMap<T>(componentDefinition.type)
}; };
const feature = componentDefinition.features; const feature = componentDefinition.features;
feature && feature.forEach((fn) => fn(def)); feature && feature.forEach((fn) => fn(def));
@ -65,7 +67,7 @@ type OnChangesExpando = OnChanges & {
}; };
export function NgOnChangesFeature<T>(type: Type<T>): (definition: DirectiveDef<any>) => void { export function NgOnChangesFeature<T>(type: Type<T>): (definition: DirectiveDef<any>) => void {
return function(definition: DirectiveDef<any>): void { return function (definition: DirectiveDef<any>): void {
const inputs = definition.inputs; const inputs = definition.inputs;
const proto = type.prototype; const proto = type.prototype;
// Place where we will store SimpleChanges if there is a change // Place where we will store SimpleChanges if there is a change
@ -80,11 +82,11 @@ export function NgOnChangesFeature<T>(type: Type<T>): (definition: DirectiveDef<
// create a getter and setter for property // create a getter and setter for property
Object.defineProperty(proto, minKey, { Object.defineProperty(proto, minKey, {
get: function(this: OnChangesExpando) { get: function (this: OnChangesExpando) {
return (existingDesc && existingDesc.get) ? existingDesc.get.call(this) : return (existingDesc && existingDesc.get) ? existingDesc.get.call(this) :
this[privateMinKey]; this[privateMinKey];
}, },
set: function(this: OnChangesExpando, value: any) { set: function (this: OnChangesExpando, value: any) {
let simpleChanges = this[PRIVATE_PREFIX]; let simpleChanges = this[PRIVATE_PREFIX];
let isFirstChange = simpleChanges === undefined; let isFirstChange = simpleChanges === undefined;
if (simpleChanges == null) { if (simpleChanges == null) {
@ -92,12 +94,12 @@ export function NgOnChangesFeature<T>(type: Type<T>): (definition: DirectiveDef<
} }
simpleChanges[pubKey] = new SimpleChange(this[privateMinKey], value, isFirstChange); simpleChanges[pubKey] = new SimpleChange(this[privateMinKey], value, isFirstChange);
(existingDesc && existingDesc.set) ? existingDesc.set.call(this, value) : (existingDesc && existingDesc.set) ? existingDesc.set.call(this, value) :
this[privateMinKey] = value; this[privateMinKey] = value;
} }
}); });
} }
proto.ngDoCheck = (function(delegateDoCheck) { proto.ngDoCheck = (function (delegateDoCheck) {
return function(this: OnChangesExpando) { return function (this: OnChangesExpando) {
let simpleChanges = this[PRIVATE_PREFIX]; let simpleChanges = this[PRIVATE_PREFIX];
if (simpleChanges != null) { if (simpleChanges != null) {
this.ngOnChanges(simpleChanges); this.ngOnChanges(simpleChanges);
@ -109,6 +111,25 @@ export function NgOnChangesFeature<T>(type: Type<T>): (definition: DirectiveDef<
}; };
} }
/**
* Takes the component type and returns a formatted map of lifecycle hooks for that
* component.
*
* @param type The component type
*/
function getLifecyleHooksMap<T>(type: Type<T>): LifecycleHooksMap {
return {
onInit: type.prototype.ngOnInit || null,
doCheck: type.prototype.ngDoCheck || null,
afterContentInit: type.prototype.ngAfterContentInit || null,
afterContentChecked: type.prototype.ngAfterContentChecked || null,
afterViewInit: type.prototype.ngAfterViewInit || null,
afterViewChecked: type.prototype.ngAfterViewChecked || null,
onDestroy: type.prototype.ngOnDestroy || null,
};
}
export function PublicFeature<T>(definition: DirectiveDef<T>) { export function PublicFeature<T>(definition: DirectiveDef<T>) {
definition.diPublic = diPublic; definition.diPublic = diPublic;
} }

View File

@ -19,7 +19,7 @@ import {Type} from '../type';
import {assertLessThan} from './assert'; import {assertLessThan} from './assert';
import {assertPreviousIsParent, getPreviousOrParentNode, getRenderer, renderEmbeddedTemplate} from './instructions'; import {assertPreviousIsParent, getPreviousOrParentNode, getRenderer, renderEmbeddedTemplate} from './instructions';
import {ComponentTemplate, DirectiveDef, TypedDirectiveDef} from './interfaces/definition'; import {ComponentTemplate, DirectiveDef} from './interfaces/definition';
import {LInjector} from './interfaces/injector'; import {LInjector} from './interfaces/injector';
import {LContainerNode, LElementNode, LNode, LNodeFlags, LViewNode} from './interfaces/node'; import {LContainerNode, LElementNode, LNode, LNodeFlags, LViewNode} from './interfaces/node';
import {QueryReadType} from './interfaces/query'; import {QueryReadType} from './interfaces/query';
@ -158,7 +158,7 @@ function createInjectionError(text: string, token: any) {
* @param di The node injector in which a directive will be added * @param di The node injector in which a directive will be added
* @param def The definition of the directive to be made public * @param def The definition of the directive to be made public
*/ */
export function diPublicInInjector(di: LInjector, def: TypedDirectiveDef<any>): void { export function diPublicInInjector(di: LInjector, def: DirectiveDef<any>): void {
bloomAdd(di, def.type); bloomAdd(di, def.type);
} }
@ -291,7 +291,7 @@ export function getOrCreateInjectable<T>(
for (let i = start, ii = start + size; i < ii; i++) { 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), // Get the definition for the directive at this index and, if it is injectable (diPublic),
// and matches the given token, return the directive instance. // and matches the given token, return the directive instance.
const directiveDef = tData[i] as TypedDirectiveDef<any>; const directiveDef = tData[i] as DirectiveDef<any>;
if (directiveDef.diPublic && directiveDef.type == token) { if (directiveDef.diPublic && directiveDef.type == token) {
return node.view.data[i]; return node.view.data[i];
} }

View File

@ -24,7 +24,7 @@ import {LContainerNode, LElementNode, LNode, LNodeFlags, LProjectionNode, LTextN
import {assertNodeType, assertNodeOfPossibleTypes} from './node_assert'; import {assertNodeType, assertNodeOfPossibleTypes} from './node_assert';
import {appendChild, insertChild, insertView, processProjectedNode, removeView} from './node_manipulation'; import {appendChild, insertChild, insertView, processProjectedNode, removeView} from './node_manipulation';
import {isNodeMatchingSelector} from './node_selector_matcher'; import {isNodeMatchingSelector} from './node_selector_matcher';
import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveType, TypedDirectiveDef, TypedComponentDef} from './interfaces/definition'; import {ComponentDef, ComponentTemplate, ComponentType, DirectiveDef, DirectiveType} from './interfaces/definition';
import {RComment, RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, ObjectOrientedRenderer3, RendererStyleFlags3} from './interfaces/renderer'; import {RComment, RElement, RText, Renderer3, RendererFactory3, ProceduralRenderer3, ObjectOrientedRenderer3, RendererStyleFlags3} from './interfaces/renderer';
import {isDifferent, stringify} from './util'; import {isDifferent, stringify} from './util';
@ -447,8 +447,6 @@ export function elementStart(
if (hostComponentDef) { if (hostComponentDef) {
// TODO(mhevery): This assumes that the directives come in correct order, which // TODO(mhevery): This assumes that the directives come in correct order, which
// is not guaranteed. Must be refactored to take it into account. // 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); directiveCreate(++index, hostComponentDef.n(), hostComponentDef, queryName);
} }
hack_declareDirectives(index, directiveTypes, localRefs); hack_declareDirectives(index, directiveTypes, localRefs);
@ -476,7 +474,6 @@ function hack_declareDirectives(
// TODO(misko): refactor this to store the `DirectiveDef` in `TView.data`. // TODO(misko): refactor this to store the `DirectiveDef` in `TView.data`.
const directiveType = directiveTypes[i]; const directiveType = directiveTypes[i];
const directiveDef = directiveType.ngDirectiveDef; const directiveDef = directiveType.ngDirectiveDef;
(directiveDef as TypedDirectiveDef<any>).type = directiveType;
directiveCreate( directiveCreate(
++index, directiveDef.n(), directiveDef, hack_findQueryName(directiveDef, localRefs)); ++index, directiveDef.n(), directiveDef, hack_findQueryName(directiveDef, localRefs));
} }

View File

@ -27,6 +27,9 @@ export const enum DirectiveDefFlags {ContentQuery = 0b10}
* `DirectiveDef` is a compiled version of the Directive used by the renderer instructions. * `DirectiveDef` is a compiled version of the Directive used by the renderer instructions.
*/ */
export interface DirectiveDef<T> { export interface DirectiveDef<T> {
/** Token representing the directive. Used by DI. */
type: Type<T>;
/** Function that makes a directive public to the DI system. */ /** Function that makes a directive public to the DI system. */
diPublic: ((def: DirectiveDef<any>) => void)|null; diPublic: ((def: DirectiveDef<any>) => void)|null;
@ -85,6 +88,9 @@ export interface DirectiveDef<T> {
// (for backwards compatibility). Child template processing thus needs to be // (for backwards compatibility). Child template processing thus needs to be
// delayed until all inputs and host bindings in a view have been checked. // delayed until all inputs and host bindings in a view have been checked.
h(directiveIndex: number, elementIndex: number): void; h(directiveIndex: number, elementIndex: number): void;
/* A map of the lifecycle hooks defined on this directive (key: name, value: fn) */
lifecycleHooks: LifecycleHooksMap;
} }
export interface ComponentDef<T> extends DirectiveDef<T> { export interface ComponentDef<T> extends DirectiveDef<T> {
@ -122,17 +128,19 @@ export interface ComponentDef<T> extends DirectiveDef<T> {
readonly rendererType: RendererType2|null; readonly rendererType: RendererType2|null;
} }
/** /* A map of the lifecycle hooks defined on a directive (key: name, value: fn) */
* Private: do not export export interface LifecycleHooksMap {
*/ onInit: () => void | null;
export interface TypedDirectiveDef<T> extends DirectiveDef<T> { type: DirectiveType<T>; } doCheck: () => void | null;
afterContentInit: () => void | null;
/** afterContentChecked: () => void | null;
* Private: do not export afterViewInit: () => void | null;
*/ afterViewChecked: () => void | null;
export interface TypedComponentDef<T> extends ComponentDef<T> { type: ComponentType<T>; } onDestroy: () => void | null;
}
export interface DirectiveDefArgs<T> { export interface DirectiveDefArgs<T> {
type: Type<T>;
factory: () => T; factory: () => T;
refresh?: (directiveIndex: number, elementIndex: number) => void; refresh?: (directiveIndex: number, elementIndex: number) => void;
inputs?: {[P in keyof T]?: string}; inputs?: {[P in keyof T]?: string};

View File

@ -18,7 +18,7 @@ import {Type} from '../type';
import {assertNotNull} from './assert'; import {assertNotNull} from './assert';
import {ReadFromInjectorFn, getOrCreateNodeInjectorForNode} from './di'; import {ReadFromInjectorFn, getOrCreateNodeInjectorForNode} from './di';
import {assertPreviousIsParent, getCurrentQuery} from './instructions'; import {assertPreviousIsParent, getCurrentQuery} from './instructions';
import {DirectiveDef, TypedDirectiveDef, unusedValueExportToPlacateAjd as unused1} from './interfaces/definition'; import {DirectiveDef, unusedValueExportToPlacateAjd as unused1} from './interfaces/definition';
import {LInjector, unusedValueExportToPlacateAjd as unused2} from './interfaces/injector'; import {LInjector, unusedValueExportToPlacateAjd as unused2} from './interfaces/injector';
import {LContainerNode, LElementNode, LNode, LNodeFlags, LViewNode, TNode, unusedValueExportToPlacateAjd as unused3} from './interfaces/node'; import {LContainerNode, LElementNode, LNode, LNodeFlags, LViewNode, TNode, unusedValueExportToPlacateAjd as unused3} from './interfaces/node';
import {LQuery, QueryReadType, unusedValueExportToPlacateAjd as unused4} from './interfaces/query'; import {LQuery, QueryReadType, unusedValueExportToPlacateAjd as unused4} from './interfaces/query';
@ -159,7 +159,7 @@ function geIdxOfMatchingDirective(node: LNode, type: Type<any>): number|null {
for (let i = flags >> LNodeFlags.INDX_SHIFT, for (let i = flags >> LNodeFlags.INDX_SHIFT,
ii = i + ((flags & LNodeFlags.SIZE_MASK) >> LNodeFlags.SIZE_SHIFT); ii = i + ((flags & LNodeFlags.SIZE_MASK) >> LNodeFlags.SIZE_SHIFT);
i < ii; i++) { i < ii; i++) {
const def = tData[i] as TypedDirectiveDef<any>; const def = tData[i] as DirectiveDef<any>;
if (def.diPublic && def.type === type) { if (def.diPublic && def.type === type) {
return i; return i;
} }

View File

@ -32,6 +32,7 @@ describe('iv perf test', () => {
it(`${iteration}. create ${count} divs in Render3`, () => { it(`${iteration}. create ${count} divs in Render3`, () => {
class Component { class Component {
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: Component,
tag: 'div', tag: 'div',
template: function Template(ctx: any, cm: any) { template: function Template(ctx: any, cm: any) {
if (cm) { if (cm) {

View File

@ -27,6 +27,7 @@ describe('compiler specification', () => {
class MyComponent { class MyComponent {
// NORMATIVE // NORMATIVE
static ngComponentDef = r3.defineComponent({ static ngComponentDef = r3.defineComponent({
type: MyComponent,
tag: 'my-component', tag: 'my-component',
factory: () => new MyComponent(), factory: () => new MyComponent(),
template: function(ctx: MyComponent, cm: boolean) { template: function(ctx: MyComponent, cm: boolean) {
@ -59,6 +60,7 @@ describe('compiler specification', () => {
constructor() { log.push('ChildComponent'); } constructor() { log.push('ChildComponent'); }
// NORMATIVE // NORMATIVE
static ngComponentDef = r3.defineComponent({ static ngComponentDef = r3.defineComponent({
type: ChildComponent,
tag: `child`, tag: `child`,
factory: () => new ChildComponent(), factory: () => new ChildComponent(),
template: function(ctx: ChildComponent, cm: boolean) { template: function(ctx: ChildComponent, cm: boolean) {
@ -77,6 +79,7 @@ describe('compiler specification', () => {
constructor() { log.push('SomeDirective'); } constructor() { log.push('SomeDirective'); }
// NORMATIVE // NORMATIVE
static ngDirectiveDef = r3.defineDirective({ static ngDirectiveDef = r3.defineDirective({
type: SomeDirective,
factory: () => new SomeDirective(), factory: () => new SomeDirective(),
}); });
// /NORMATIVE // /NORMATIVE
@ -86,6 +89,7 @@ describe('compiler specification', () => {
class MyComponent { class MyComponent {
// NORMATIVE // NORMATIVE
static ngComponentDef = r3.defineComponent({ static ngComponentDef = r3.defineComponent({
type: MyComponent,
tag: 'my-component', tag: 'my-component',
factory: () => new MyComponent(), factory: () => new MyComponent(),
template: function(ctx: MyComponent, cm: boolean) { template: function(ctx: MyComponent, cm: boolean) {
@ -119,6 +123,7 @@ describe('compiler specification', () => {
constructor(template: TemplateRef<any>) { log.push('ifDirective'); } constructor(template: TemplateRef<any>) { log.push('ifDirective'); }
// NORMATIVE // NORMATIVE
static ngDirectiveDef = r3.defineDirective({ static ngDirectiveDef = r3.defineDirective({
type: IfDirective,
factory: () => new IfDirective(r3.injectTemplateRef()), factory: () => new IfDirective(r3.injectTemplateRef()),
}); });
// /NORMATIVE // /NORMATIVE
@ -130,6 +135,7 @@ describe('compiler specification', () => {
salutation = 'Hello'; salutation = 'Hello';
// NORMATIVE // NORMATIVE
static ngComponentDef = r3.defineComponent({ static ngComponentDef = r3.defineComponent({
type: MyComponent,
tag: 'my-component', tag: 'my-component',
factory: () => new MyComponent(), factory: () => new MyComponent(),
template: function(ctx: MyComponent, cm: boolean) { template: function(ctx: MyComponent, cm: boolean) {
@ -236,6 +242,7 @@ describe('compiler specification', () => {
class MyComponent { class MyComponent {
// NORMATIVE // NORMATIVE
static ngComponentDef = r3.defineComponent({ static ngComponentDef = r3.defineComponent({
type: MyComponent,
tag: 'my-component', tag: 'my-component',
factory: () => new MyComponent, factory: () => new MyComponent,
template: function(ctx: MyComponent, cm: boolean) { template: function(ctx: MyComponent, cm: boolean) {

View File

@ -20,6 +20,7 @@ describe('component', () => {
increment() { this.count++; } increment() { this.count++; }
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: CounterComponent,
tag: 'counter', tag: 'counter',
template: function(ctx: CounterComponent, cm: boolean) { template: function(ctx: CounterComponent, cm: boolean) {
if (cm) { if (cm) {
@ -63,6 +64,7 @@ describe('component', () => {
describe('encapsulation', () => { describe('encapsulation', () => {
class WrapperComponent { class WrapperComponent {
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: WrapperComponent,
tag: 'wrapper', tag: 'wrapper',
template: function(ctx: WrapperComponent, cm: boolean) { template: function(ctx: WrapperComponent, cm: boolean) {
if (cm) { if (cm) {
@ -78,6 +80,7 @@ describe('encapsulation', () => {
class EncapsulatedComponent { class EncapsulatedComponent {
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: EncapsulatedComponent,
tag: 'encapsulated', tag: 'encapsulated',
template: function(ctx: EncapsulatedComponent, cm: boolean) { template: function(ctx: EncapsulatedComponent, cm: boolean) {
if (cm) { if (cm) {
@ -96,6 +99,7 @@ describe('encapsulation', () => {
class LeafComponent { class LeafComponent {
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: LeafComponent,
tag: 'leaf', tag: 'leaf',
template: function(ctx: LeafComponent, cm: boolean) { template: function(ctx: LeafComponent, cm: boolean) {
if (cm) { if (cm) {
@ -125,6 +129,7 @@ describe('encapsulation', () => {
it('should encapsulate host and children with different attributes', () => { it('should encapsulate host and children with different attributes', () => {
class WrapperComponentWith { class WrapperComponentWith {
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: WrapperComponentWith,
tag: 'wrapper', tag: 'wrapper',
template: function(ctx: WrapperComponentWith, cm: boolean) { template: function(ctx: WrapperComponentWith, cm: boolean) {
if (cm) { if (cm) {
@ -142,6 +147,7 @@ describe('encapsulation', () => {
class LeafComponentwith { class LeafComponentwith {
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: LeafComponentwith,
tag: 'leaf', tag: 'leaf',
template: function(ctx: LeafComponentwith, cm: boolean) { template: function(ctx: LeafComponentwith, cm: boolean) {
if (cm) { if (cm) {

View File

@ -22,7 +22,7 @@ describe('di', () => {
it('should create directive with no deps', () => { it('should create directive with no deps', () => {
class Directive { class Directive {
value: string = 'Created'; value: string = 'Created';
static ngDirectiveDef = defineDirective({factory: () => new Directive}); static ngDirectiveDef = defineDirective({type: Directive, factory: () => new Directive});
} }
function Template(ctx: any, cm: boolean) { function Template(ctx: any, cm: boolean) {
@ -42,21 +42,23 @@ describe('di', () => {
it('should create directive with inter view dependencies', () => { it('should create directive with inter view dependencies', () => {
class DirectiveA { class DirectiveA {
value: string = 'A'; value: string = 'A';
static ngDirectiveDef = static ngDirectiveDef = defineDirective(
defineDirective({factory: () => new DirectiveA, features: [PublicFeature]}); {type: DirectiveA, factory: () => new DirectiveA, features: [PublicFeature]});
} }
class DirectiveB { class DirectiveB {
value: string = 'B'; value: string = 'B';
static ngDirectiveDef = static ngDirectiveDef = defineDirective(
defineDirective({factory: () => new DirectiveB, features: [PublicFeature]}); {type: DirectiveB, factory: () => new DirectiveB, features: [PublicFeature]});
} }
class DirectiveC { class DirectiveC {
value: string; value: string;
constructor(a: DirectiveA, b: DirectiveB) { this.value = a.value + b.value; } constructor(a: DirectiveA, b: DirectiveB) { this.value = a.value + b.value; }
static ngDirectiveDef = defineDirective( static ngDirectiveDef = defineDirective({
{factory: () => new DirectiveC(inject(DirectiveA), inject(DirectiveB))}); type: DirectiveC,
factory: () => new DirectiveC(inject(DirectiveA), inject(DirectiveB))
});
} }
function Template(ctx: any, cm: boolean) { function Template(ctx: any, cm: boolean) {
@ -83,8 +85,11 @@ describe('di', () => {
constructor(public elementRef: ElementRef) { constructor(public elementRef: ElementRef) {
this.value = (elementRef.constructor as any).name; this.value = (elementRef.constructor as any).name;
} }
static ngDirectiveDef = defineDirective( static ngDirectiveDef = defineDirective({
{factory: () => new Directive(injectElementRef()), features: [PublicFeature]}); type: Directive,
factory: () => new Directive(injectElementRef()),
features: [PublicFeature]
});
} }
class DirectiveSameInstance { class DirectiveSameInstance {
@ -92,8 +97,10 @@ describe('di', () => {
constructor(elementRef: ElementRef, directive: Directive) { constructor(elementRef: ElementRef, directive: Directive) {
this.value = elementRef === directive.elementRef; this.value = elementRef === directive.elementRef;
} }
static ngDirectiveDef = defineDirective( static ngDirectiveDef = defineDirective({
{factory: () => new DirectiveSameInstance(injectElementRef(), inject(Directive))}); type: DirectiveSameInstance,
factory: () => new DirectiveSameInstance(injectElementRef(), inject(Directive))
});
} }
function Template(ctx: any, cm: boolean) { function Template(ctx: any, cm: boolean) {
@ -116,8 +123,11 @@ describe('di', () => {
constructor(public templateRef: TemplateRef<any>) { constructor(public templateRef: TemplateRef<any>) {
this.value = (templateRef.constructor as any).name; this.value = (templateRef.constructor as any).name;
} }
static ngDirectiveDef = defineDirective( static ngDirectiveDef = defineDirective({
{factory: () => new Directive(injectTemplateRef()), features: [PublicFeature]}); type: Directive,
factory: () => new Directive(injectTemplateRef()),
features: [PublicFeature]
});
} }
class DirectiveSameInstance { class DirectiveSameInstance {
@ -125,8 +135,10 @@ describe('di', () => {
constructor(templateRef: TemplateRef<any>, directive: Directive) { constructor(templateRef: TemplateRef<any>, directive: Directive) {
this.value = templateRef === directive.templateRef; this.value = templateRef === directive.templateRef;
} }
static ngDirectiveDef = defineDirective( static ngDirectiveDef = defineDirective({
{factory: () => new DirectiveSameInstance(injectTemplateRef(), inject(Directive))}); type: DirectiveSameInstance,
factory: () => new DirectiveSameInstance(injectTemplateRef(), inject(Directive))
});
} }
@ -149,8 +161,11 @@ describe('di', () => {
constructor(public viewContainerRef: ViewContainerRef) { constructor(public viewContainerRef: ViewContainerRef) {
this.value = (viewContainerRef.constructor as any).name; this.value = (viewContainerRef.constructor as any).name;
} }
static ngDirectiveDef = defineDirective( static ngDirectiveDef = defineDirective({
{factory: () => new Directive(injectViewContainerRef()), features: [PublicFeature]}); type: Directive,
factory: () => new Directive(injectViewContainerRef()),
features: [PublicFeature]
});
} }
class DirectiveSameInstance { class DirectiveSameInstance {
@ -159,6 +174,7 @@ describe('di', () => {
this.value = viewContainerRef === directive.viewContainerRef; this.value = viewContainerRef === directive.viewContainerRef;
} }
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: DirectiveSameInstance,
factory: () => new DirectiveSameInstance(injectViewContainerRef(), inject(Directive)) factory: () => new DirectiveSameInstance(injectViewContainerRef(), inject(Directive))
}); });
} }
@ -237,8 +253,11 @@ describe('di', () => {
it('should inject from parent view', () => { it('should inject from parent view', () => {
class ParentDirective { class ParentDirective {
static ngDirectiveDef = static ngDirectiveDef = defineDirective({
defineDirective({factory: () => new ParentDirective(), features: [PublicFeature]}); type: ParentDirective,
factory: () => new ParentDirective(),
features: [PublicFeature]
});
} }
class ChildDirective { class ChildDirective {
@ -247,6 +266,7 @@ describe('di', () => {
this.value = (parent.constructor as any).name; this.value = (parent.constructor as any).name;
} }
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: ChildDirective,
factory: () => new ChildDirective(inject(ParentDirective)), factory: () => new ChildDirective(inject(ParentDirective)),
features: [PublicFeature] features: [PublicFeature]
}); });
@ -257,8 +277,10 @@ describe('di', () => {
constructor(parent: ParentDirective, child: ChildDirective) { constructor(parent: ParentDirective, child: ChildDirective) {
this.value = parent === child.parent; this.value = parent === child.parent;
} }
static ngDirectiveDef = defineDirective( static ngDirectiveDef = defineDirective({
{factory: () => new Child2Directive(inject(ParentDirective), inject(ChildDirective))}); type: Child2Directive,
factory: () => new Child2Directive(inject(ParentDirective), inject(ChildDirective))
});
} }
function Template(ctx: any, cm: boolean) { function Template(ctx: any, cm: boolean) {

View File

@ -20,6 +20,7 @@ describe('directive', () => {
class Directive { class Directive {
klass = 'foo'; klass = 'foo';
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: Directive,
factory: () => directiveInstance = new Directive, factory: () => directiveInstance = new Directive,
refresh: (directiveIndex: number, elementIndex: number) => { refresh: (directiveIndex: number, elementIndex: number) => {
p(elementIndex, 'className', b(m<Directive>(directiveIndex).klass)); p(elementIndex, 'className', b(m<Directive>(directiveIndex).klass));

View File

@ -42,8 +42,12 @@ describe('exports', () => {
class MyComponent { class MyComponent {
name = 'Nancy'; name = 'Nancy';
static ngComponentDef = static ngComponentDef = defineComponent({
defineComponent({tag: 'comp', template: function() {}, factory: () => new MyComponent}); type: MyComponent,
tag: 'comp',
template: function() {},
factory: () => new MyComponent
});
} }
expect(renderToHtml(Template, {})).toEqual('<comp></comp>Nancy'); expect(renderToHtml(Template, {})).toEqual('<comp></comp>Nancy');
@ -55,14 +59,19 @@ describe('exports', () => {
let myDir: MyDir; let myDir: MyDir;
class MyComponent { class MyComponent {
constructor() { myComponent = this; } constructor() { myComponent = this; }
static ngComponentDef = static ngComponentDef = defineComponent({
defineComponent({tag: 'comp', template: function() {}, factory: () => new MyComponent}); type: MyComponent,
tag: 'comp',
template: function() {},
factory: () => new MyComponent
});
} }
class MyDir { class MyDir {
myDir: MyComponent; myDir: MyComponent;
constructor() { myDir = this; } constructor() { myDir = this; }
static ngDirectiveDef = defineDirective({factory: () => new MyDir, inputs: {myDir: 'myDir'}}); static ngDirectiveDef =
defineDirective({type: MyDir, factory: () => new MyDir, inputs: {myDir: 'myDir'}});
} }
/** <comp #myComp></comp> <div [myDir]="myComp"></div> */ /** <comp #myComp></comp> <div [myDir]="myComp"></div> */
@ -94,7 +103,7 @@ describe('exports', () => {
class SomeDir { class SomeDir {
name = 'Drew'; name = 'Drew';
static ngDirectiveDef = defineDirective({factory: () => new SomeDir}); static ngDirectiveDef = defineDirective({type: SomeDir, factory: () => new SomeDir});
} }
expect(renderToHtml(Template, {})).toEqual('<div></div>Drew'); expect(renderToHtml(Template, {})).toEqual('<div></div>Drew');
@ -175,6 +184,7 @@ describe('exports', () => {
constructor() { myComponent = this; } constructor() { myComponent = this; }
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: MyComponent,
tag: 'comp', tag: 'comp',
template: function(ctx: MyComponent, cm: boolean) {}, template: function(ctx: MyComponent, cm: boolean) {},
factory: () => new MyComponent factory: () => new MyComponent
@ -187,7 +197,7 @@ describe('exports', () => {
constructor() { myDir = this; } constructor() { myDir = this; }
static ngDirectiveDef = static ngDirectiveDef =
defineDirective({factory: () => new MyDir, inputs: {myDir: 'myDir'}}); defineDirective({type: MyDir, factory: () => new MyDir, inputs: {myDir: 'myDir'}});
} }
/** <div [myDir]="myComp"></div><comp #myComp></comp> */ /** <div [myDir]="myComp"></div><comp #myComp></comp> */
@ -230,8 +240,12 @@ describe('exports', () => {
constructor() { myComponent = this; } constructor() { myComponent = this; }
static ngComponentDef = static ngComponentDef = defineComponent({
defineComponent({tag: 'comp', template: function() {}, factory: () => new MyComponent}); type: MyComponent,
tag: 'comp',
template: function() {},
factory: () => new MyComponent
});
} }
expect(renderToHtml(Template, {})).toEqual('oneNancy<comp></comp><input value="one">'); expect(renderToHtml(Template, {})).toEqual('oneNancy<comp></comp><input value="one">');
}); });

View File

@ -210,6 +210,7 @@ describe('render3 integration test', () => {
value = ' one'; value = ' one';
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: TodoComponent,
tag: 'todo', tag: 'todo',
template: function TodoTemplate(ctx: any, cm: boolean) { template: function TodoTemplate(ctx: any, cm: boolean) {
if (cm) { if (cm) {
@ -279,6 +280,7 @@ describe('render3 integration test', () => {
class TodoComponentHostBinding { class TodoComponentHostBinding {
title = 'one'; title = 'one';
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: TodoComponentHostBinding,
tag: 'todo', tag: 'todo',
template: function TodoComponentHostBindingTemplate( template: function TodoComponentHostBindingTemplate(
ctx: TodoComponentHostBinding, cm: boolean) { ctx: TodoComponentHostBinding, cm: boolean) {
@ -314,6 +316,7 @@ describe('render3 integration test', () => {
class MyComp { class MyComp {
name = 'Bess'; name = 'Bess';
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: MyComp,
tag: 'comp', tag: 'comp',
template: function MyCompTemplate(ctx: any, cm: boolean) { template: function MyCompTemplate(ctx: any, cm: boolean) {
if (cm) { if (cm) {
@ -348,6 +351,7 @@ describe('render3 integration test', () => {
class MyComp { class MyComp {
condition: boolean; condition: boolean;
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: MyComp,
tag: 'comp', tag: 'comp',
template: function MyCompTemplate(ctx: any, cm: boolean) { template: function MyCompTemplate(ctx: any, cm: boolean) {
if (cm) { if (cm) {

View File

@ -49,6 +49,7 @@ describe('lifecycles', () => {
ngOnInit() { events.push(`${name}${this.val}`); } ngOnInit() { events.push(`${name}${this.val}`); }
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: Component,
tag: name, tag: name,
factory: () => new Component(), factory: () => new Component(),
hostBindings: function(directiveIndex: number, elementIndex: number): hostBindings: function(directiveIndex: number, elementIndex: number):
@ -339,6 +340,7 @@ describe('lifecycles', () => {
ngOnInit() { allEvents.push('ngOnInit ' + name); } ngOnInit() { allEvents.push('ngOnInit ' + name); }
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: Component,
tag: name, tag: name,
factory: () => new Component(), factory: () => new Component(),
hostBindings: function( hostBindings: function(
@ -452,8 +454,13 @@ describe('lifecycles', () => {
} }
ngAfterContentChecked() { allEvents.push(`${name}${this.val} check`); } ngAfterContentChecked() { allEvents.push(`${name}${this.val} check`); }
static ngComponentDef = defineComponent( static ngComponentDef = defineComponent({
{tag: name, factory: () => new Component(), inputs: {val: 'val'}, template: template}); type: Component,
tag: name,
factory: () => new Component(),
inputs: {val: 'val'},
template: template,
});
}; };
} }
@ -516,7 +523,7 @@ describe('lifecycles', () => {
class Directive { class Directive {
ngAfterContentInit() { events.push('dir'); } ngAfterContentInit() { events.push('dir'); }
static ngDirectiveDef = defineDirective({factory: () => new Directive()}); static ngDirectiveDef = defineDirective({type: Directive, factory: () => new Directive()});
} }
function Template(ctx: any, cm: boolean) { function Template(ctx: any, cm: boolean) {
@ -816,6 +823,7 @@ describe('lifecycles', () => {
ngAfterViewChecked() { allEvents.push(`${name}${this.val} check`); } ngAfterViewChecked() { allEvents.push(`${name}${this.val} check`); }
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: Component,
tag: name, tag: name,
factory: () => new Component(), factory: () => new Component(),
refresh: (directiveIndex: number, elementIndex: number) => { refresh: (directiveIndex: number, elementIndex: number) => {
@ -1227,8 +1235,13 @@ describe('lifecycles', () => {
val: string = ''; val: string = '';
ngOnDestroy() { events.push(`${name}${this.val}`); } ngOnDestroy() { events.push(`${name}${this.val}`); }
static ngComponentDef = defineComponent( static ngComponentDef = defineComponent({
{tag: name, factory: () => new Component(), inputs: {val: 'val'}, template: template}); type: Component,
tag: name,
factory: () => new Component(),
inputs: {val: 'val'},
template: template
});
}; };
} }
@ -1677,6 +1690,7 @@ describe('lifecycles', () => {
ngAfterViewChecked() { events.push(`viewCheck ${name}${this.val}`); } ngAfterViewChecked() { events.push(`viewCheck ${name}${this.val}`); }
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: Component,
tag: name, tag: name,
factory: () => new Component(), factory: () => new Component(),
hostBindings: function(directiveIndex: number, elementIndex: number): void { hostBindings: function(directiveIndex: number, elementIndex: number): void {

View File

@ -21,6 +21,7 @@ describe('event listeners', () => {
onClick() { this.counter++; } onClick() { this.counter++; }
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: MyComp,
tag: 'comp', tag: 'comp',
/** <button (click)="onClick()"> Click me </button> */ /** <button (click)="onClick()"> Click me </button> */
template: function CompTemplate(ctx: any, cm: boolean) { template: function CompTemplate(ctx: any, cm: boolean) {

View File

@ -20,6 +20,7 @@ describe('outputs', () => {
resetStream = new EventEmitter(); resetStream = new EventEmitter();
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: ButtonToggle,
tag: 'button-toggle', tag: 'button-toggle',
template: function(ctx: any, cm: boolean) {}, template: function(ctx: any, cm: boolean) {},
factory: () => buttonToggle = new ButtonToggle(), factory: () => buttonToggle = new ButtonToggle(),
@ -32,8 +33,11 @@ describe('outputs', () => {
class OtherDir { class OtherDir {
changeStream = new EventEmitter(); changeStream = new EventEmitter();
static ngDirectiveDef = defineDirective( static ngDirectiveDef = defineDirective({
{factory: () => otherDir = new OtherDir, outputs: {changeStream: 'change'}}); type: OtherDir,
factory: () => otherDir = new OtherDir,
outputs: {changeStream: 'change'}
});
} }
it('should call component output function when event is emitted', () => { it('should call component output function when event is emitted', () => {
@ -212,6 +216,7 @@ describe('outputs', () => {
ngOnDestroy() { this.events.push('destroy'); } ngOnDestroy() { this.events.push('destroy'); }
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: DestroyComp,
tag: 'destroy-comp', tag: 'destroy-comp',
template: function(ctx: any, cm: boolean) {}, template: function(ctx: any, cm: boolean) {},
factory: () => destroyComp = new DestroyComp() factory: () => destroyComp = new DestroyComp()
@ -287,8 +292,8 @@ describe('outputs', () => {
class MyButton { class MyButton {
click = new EventEmitter(); click = new EventEmitter();
static ngDirectiveDef = static ngDirectiveDef = defineDirective(
defineDirective({factory: () => buttonDir = new MyButton, outputs: {click: 'click'}}); {type: MyButton, factory: () => buttonDir = new MyButton, outputs: {click: 'click'}});
} }
function Template(ctx: any, cm: boolean) { function Template(ctx: any, cm: boolean) {
@ -340,8 +345,8 @@ describe('outputs', () => {
class OtherDir { class OtherDir {
change: boolean; change: boolean;
static ngDirectiveDef = static ngDirectiveDef = defineDirective(
defineDirective({factory: () => otherDir = new OtherDir, inputs: {change: 'change'}}); {type: OtherDir, factory: () => otherDir = new OtherDir, inputs: {change: 'change'}});
} }
/** <button-toggle (change)="onChange()" otherDir [change]="change"></button-toggle> */ /** <button-toggle (change)="onChange()" otherDir [change]="change"></button-toggle> */

View File

@ -69,8 +69,8 @@ describe('elementProperty', () => {
class MyButton { class MyButton {
disabled: boolean; disabled: boolean;
static ngDirectiveDef = static ngDirectiveDef = defineDirective(
defineDirective({factory: () => button = new MyButton(), inputs: {disabled: 'disabled'}}); {type: MyButton, factory: () => button = new MyButton(), inputs: {disabled: 'disabled'}});
} }
class OtherDir { class OtherDir {
@ -78,6 +78,7 @@ describe('elementProperty', () => {
clickStream = new EventEmitter(); clickStream = new EventEmitter();
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: OtherDir,
factory: () => otherDir = new OtherDir(), factory: () => otherDir = new OtherDir(),
inputs: {id: 'id'}, inputs: {id: 'id'},
outputs: {clickStream: 'click'} outputs: {clickStream: 'click'}
@ -140,6 +141,7 @@ describe('elementProperty', () => {
id: number; id: number;
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: Comp,
tag: 'comp', tag: 'comp',
template: function(ctx: any, cm: boolean) {}, template: function(ctx: any, cm: boolean) {},
factory: () => comp = new Comp(), factory: () => comp = new Comp(),
@ -172,6 +174,7 @@ describe('elementProperty', () => {
disabled: boolean; disabled: boolean;
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: OtherDisabledDir,
factory: () => otherDisabledDir = new OtherDisabledDir(), factory: () => otherDisabledDir = new OtherDisabledDir(),
inputs: {disabled: 'disabled'} inputs: {disabled: 'disabled'}
}); });
@ -231,8 +234,8 @@ describe('elementProperty', () => {
class IdDir { class IdDir {
idNumber: number; idNumber: number;
static ngDirectiveDef = static ngDirectiveDef = defineDirective(
defineDirective({factory: () => idDir = new IdDir(), inputs: {idNumber: 'id'}}); {type: IdDir, factory: () => idDir = new IdDir(), inputs: {idNumber: 'id'}});
} }
/** /**
@ -294,6 +297,7 @@ describe('elementProperty', () => {
changeStream = new EventEmitter(); changeStream = new EventEmitter();
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: MyDir,
factory: () => myDir = new MyDir(), factory: () => myDir = new MyDir(),
inputs: {role: 'role', direction: 'dir'}, inputs: {role: 'role', direction: 'dir'},
outputs: {changeStream: 'change'} outputs: {changeStream: 'change'}
@ -304,8 +308,8 @@ describe('elementProperty', () => {
class MyDirB { class MyDirB {
roleB: string; roleB: string;
static ngDirectiveDef = static ngDirectiveDef = defineDirective(
defineDirective({factory: () => dirB = new MyDirB(), inputs: {roleB: 'role'}}); {type: MyDirB, factory: () => dirB = new MyDirB(), inputs: {roleB: 'role'}});
} }
it('should set input property based on attribute if existing', () => { it('should set input property based on attribute if existing', () => {
@ -467,6 +471,7 @@ describe('elementProperty', () => {
class Comp { class Comp {
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: Comp,
tag: 'comp', tag: 'comp',
template: function(ctx: any, cm: boolean) { template: function(ctx: any, cm: boolean) {
if (cm) { if (cm) {

View File

@ -82,14 +82,20 @@ export function createComponent(
name: string, template: ComponentTemplate<any>): ComponentType<any> { name: string, template: ComponentTemplate<any>): ComponentType<any> {
return class Component { return class Component {
value: any; value: any;
static ngComponentDef = defineComponent( static ngComponentDef = defineComponent({
{tag: name, factory: () => new Component, template: template, features: [PublicFeature]}); type: Component,
tag: name,
factory: () => new Component,
template: template,
features: [PublicFeature]
});
}; };
} }
export function createDirective({exportAs}: {exportAs?: string} = {}): DirectiveType<any> { export function createDirective({exportAs}: {exportAs?: string} = {}): DirectiveType<any> {
return class Directive { return class Directive {
static ngDirectiveDef = defineDirective({ static ngDirectiveDef = defineDirective({
type: Directive,
factory: () => new Directive(), factory: () => new Directive(),
features: [PublicFeature], features: [PublicFeature],
exportAs: exportAs, exportAs: exportAs,

View File

@ -29,6 +29,7 @@ describe('renderer factory lifecycle', () => {
class SomeComponent { class SomeComponent {
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: SomeComponent,
tag: 'some-component', tag: 'some-component',
template: function(ctx: SomeComponent, cm: boolean) { template: function(ctx: SomeComponent, cm: boolean) {
logs.push('component'); logs.push('component');
@ -42,6 +43,7 @@ describe('renderer factory lifecycle', () => {
class SomeComponentWhichThrows { class SomeComponentWhichThrows {
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: SomeComponentWhichThrows,
tag: 'some-component-with-Error', tag: 'some-component-with-Error',
template: function(ctx: SomeComponentWhichThrows, cm: boolean) { template: function(ctx: SomeComponentWhichThrows, cm: boolean) {
throw(new Error('SomeComponentWhichThrows threw')); throw(new Error('SomeComponentWhichThrows threw'));
@ -120,6 +122,7 @@ describe('animation renderer factory', () => {
class SomeComponent { class SomeComponent {
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: SomeComponent,
tag: 'some-component', tag: 'some-component',
template: function(ctx: SomeComponent, cm: boolean) { template: function(ctx: SomeComponent, cm: boolean) {
if (cm) { if (cm) {
@ -136,6 +139,7 @@ describe('animation renderer factory', () => {
eventLogs.push(`${event.fromState ? event.fromState : event.toState} - ${event.phaseName}`); eventLogs.push(`${event.fromState ? event.fromState : event.toState} - ${event.phaseName}`);
} }
static ngComponentDef = defineComponent({ static ngComponentDef = defineComponent({
type: SomeComponentWithAnimation,
tag: 'some-component', tag: 'some-component',
template: function(ctx: SomeComponentWithAnimation, cm: boolean) { template: function(ctx: SomeComponentWithAnimation, cm: boolean) {
if (cm) { if (cm) {