I\'m trying to create a library of shared Angular components to use across a number of different web projects. Along with the shared component library, I\'m trying to create
You can try using special function to get annotations:
annotation.ts
declare let Reflect: any;
export function getAnnotation(typeOrFunc: Type<any>): any[]|null {
// Prefer the direct API.
if ((<any>typeOrFunc).annotations) {
let annotations = (<any>typeOrFunc).annotations;
if (typeof annotations === 'function' && annotations.annotations) {
annotations = annotations.annotations;
}
return annotations[0];
}
// API of tsickle for lowering decorators to properties on the class.
if ((<any>typeOrFunc).decorators) {
return convertTsickleDecoratorIntoMetadata((<any>typeOrFunc).decorators)[0];
}
// API for metadata created by invoking the decorators.
if (Reflect && Reflect.getOwnMetadata) {
return Reflect.getOwnMetadata('annotations', typeOrFunc)[0];
}
return null;
}
function convertTsickleDecoratorIntoMetadata(decoratorInvocations: any[]): any[] {
if (!decoratorInvocations) {
return [];
}
return decoratorInvocations.map(decoratorInvocation => {
const decoratorType = decoratorInvocation.type;
const annotationCls = decoratorType.annotationCls;
const annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
return new annotationCls(...annotationArgs);
});
}
and then
this.encodedExampleHtml = getAnnotation(FooComponent).template;
Plunker Example
See also
Read and List all exports of an angular module
Example of how angular parses template
yurzui's answer works fine for Angular 4.4.2 but not for 5.0.2. The annotation mechanism changed: a property instead of Reflect.defineMetadata() is used to store metadata. Since it's not documented, one can only find it in the code:
const /** @type {?} */ TypeDecorator = (function TypeDecorator(cls) {
const /** @type {?} */ annotations = Reflect.getOwnMetadata('annotations', cls) || [];
annotations.push(annotationInstance);
Reflect.defineMetadata('annotations', annotations, cls);
return cls;
});
in Angular 4.4.2 (@angular/core/@angular/core.js
, l.356) to
const ANNOTATIONS = '__annotations__';
const /** @type {?} */ TypeDecorator = /** @type {?} */ (function TypeDecorator(cls) {
// Use of Object.defineProperty is important since it creates non-enumerable property which
// prevents the property is copied during subclassing.
const /** @type {?} */ annotations = cls.hasOwnProperty(ANNOTATIONS) ?
(/** @type {?} */ (cls))[ANNOTATIONS] :
Object.defineProperty(cls, ANNOTATIONS, { value: [] })[ANNOTATIONS];
annotations.push(annotationInstance);
return cls;
});
in Angular 5.0.2 (@angular/core/esm2015/core.js
, l.96).
Updated code for accessing Metadata, e.g. the template:
import 'reflect-metadata';
export function getAnnotation(typeOrFunc: Type<any>): any[]|null {
// Prefer the direct API.
if ((<any>typeOrFunc)['__annotations__']) {
return (<any>typeOrFunc)['__annotations__'][0];
}
// API of tsickle for lowering decorators to properties on the class.
if ((<any>typeOrFunc).decorators) {
return convertTsickleDecoratorIntoMetadata((<any>typeOrFunc).decorators)[0];
}
// API for metadata created by invoking the decorators.
if (Reflect && Reflect.getOwnMetadata) {
return Reflect.getOwnMetadata('annotations', typeOrFunc)[0];
}
return null;
}
function convertTsickleDecoratorIntoMetadata(decoratorInvocations: any[]): any[] {
if (!decoratorInvocations) {
return [];
}
return decoratorInvocations.map(decoratorInvocation => {
const decoratorType = decoratorInvocation.type;
const annotationCls = decoratorType.annotationCls;
const annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
return new annotationCls(...annotationArgs);
});
}