angular
April 22

Использование reflectComponentType() в Angular

Функция reflectComponentType() была добавлена в Angular v14.1.0 для извлечения следующих метаданных из компонента:

@Component({
  selector: 'standalone-component',
  standalone: true,
  template: `
    <ng-content></ng-content>
    <ng-content select="content-selector-a"></ng-content>
  `,
})
class StandaloneComponent {
  @Input() inputA: string;
  @Input('aliasB') inputB: string;

  @Output() eventA = new EventEmitter();
  @Output('aliasEvent') eventB = new EventEmitter();
}

const mirror = reflectComponentType(StandaloneComponent)!;

expect(mirror.selector).toBe('standalone-component');

expect(mirror.type).toBe(StandaloneComponent);

expect(mirror.isStandalone).toEqual(true);

expect(mirror.inputs).toEqual([
  { propName: 'inputA', templateName: 'inputA' },
  { propName: 'inputB', templateName: 'aliasB' },
]);

expect(mirror.outputs).toEqual([
  { propName: 'eventA', templateName: 'eventA' },
  { propName: 'eventB', templateName: 'aliasEvent' },
]);

expect(mirror.ngContentSelectors).toEqual(['*', 'content-selector-a']);

Эта функция имеет несколько необычных применений. Ее можно использовать для создания инструментов отладки или, например, можно использовать метаданные селектора для создания пользовательских элементов на основе существующих компонентов:

export const customElementComponents = [
  TextBoxCustomElementComponent,
  CheckBoxCustomElementComponent
  ...
]

function createCustomElements(injector: Injector){
  customElementComponents.forEach((cmp: Type<any>) => {
    const element = createCustomElement(cmp, { injector: injector })
    const selector = reflectComponentType(cmp)?.selector;
    customElements.define(selector, element);
  })
}

Мы можем использовать ее для создания динамических компонентов на основе файла JSON. В обсуждении на github больше вариантов использования.