@2ng/dynamic-component

```ts import { DynamicComponentModule } from '@2ng/dynamic-component'; ```

Usage no npm install needed!

<script type="module">
  import 2ngDynamicComponent from 'https://cdn.skypack.dev/@2ng/dynamic-component';
</script>

README

@2ng/dynamic-component

Usage

import { DynamicComponentModule } from '@2ng/dynamic-component';
<ng-container
  [dynamicComponent]="component"
  [inputs]="inputs"
  [outputs]="outputs"
></ng-container>

API

component: Type<C>

Компонент Angular

inputs: Partial<{ [input in keyof C]: C[input] }>;

Объект, ключи которого - это инпуты компонента, который будет отрисован динамически. Значение соответствует типу этого инпута.

Типизацией не смог получить только инпуты компонента, поэтому вывожу все свойства и методы класса в типах. Но внутри директивы присваиваю значение свойства только если задано значение свойству с именем инпута.

outputs: Partial<
  {
    [output in keyof C]: C[output] extends EventEmitter<infer K>
      ? (event: K) => void
      : never;
  }
>;;

Объект, ключи которого - это аутпуты компонента, который будет отрисован динамически. Значение - функция, которая будет передана в метод subscribe, при подписке на аутпут компонента.

Аналогично в типах вывожу все свойства и методы, но будет ошибка, если это свойство не экземпляр EventEmitter. Внутри директивы подписываюсь на аутпут только если свойству с именем аутпута присвоена функция .


Example

Component One

one.component.ts

import { Component, EventEmitter } from '@angular/core';

@Component({
  template: `
    <div>{{ name }}</div>
    <button (click)="showMore.emit()">Show more</div>
  `,
})
export class OneComponent {
  @Input() name: string;
  @Output() showMore = new EventEmitter<void>();
}

Component Two

two.component.html

<ng-container
  [dynamicComponent]="component"
  [inputs]="inputs"
  [outputs]="outputs"
></ng-container>

two.component.ts

import { Component } from '@angular/core';
import OneComponent from '/one.component';

@Component({...})
export class TwoComponent {
  component = OneComponent;
  inputs = {
    name: 'Andrey'
  }
  outputs = {
    showMore: () => this.onShowMore();
  }

  onShowMore() {
    console.log('show more');
  }
}