Is there a way to get the HTML template for an Angular* component?

后端 未结 2 564
-上瘾入骨i
-上瘾入骨i 2020-12-17 00:42

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

相关标签:
2条回答
  • 2020-12-17 01:23

    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

    • When and how s decorator applied to the decorated classes from the @angular packages
    • Read and List all exports of an angular module

    • Example of how angular parses template

    0 讨论(0)
  • 2020-12-17 01:25

    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);
      });
    }
    
    0 讨论(0)
提交回复
热议问题