Andrew Hill
Andrew Hill

Reputation: 2253

Construct component selector via an @Input

How does one construct a selector programmatically in Angular?

Let's say I have a parent component called header.component which looks like this;

export class ContentHeaderComponent {
  @Input() iconName: string;
}

...and I am using Angular Feather to add icons to the application which requires you to do the following to create an icon:

<i-chevron-down></i-chevron-down>

In my header component template I want to pass "chevron-down" to the tag via a parent component. In effect I am looking to do something like this in the header component:

<i-{{ iconName }}></i-{{ iconName }}>

Is constructing a selector on the fly possible in Angular?

Upvotes: 2

Views: 895

Answers (2)

Jota.Toledo
Jota.Toledo

Reputation: 28434

Your use case would be really simple if you were using a css or ligature based approach, but because your library has 1 comp per icon and there is basically no common interface among them, AFAIK there is virtually no way to map a string to its correspondent component class.

The approach suggested in the comments wont work, as angular will not create component instances from sanitized HTML.

You could try the following idea: instead of passing the icon name, you could pass a template with the desired icon and embed it in the component. This can be done as follows:

@Component({
  selector: 'foo-header'
})
export class ContentHeaderComponent {
  @Input() iconTemplate: TemplateRef<any>;
}

content-header.component.html

<ng-container *ngIf="iconTemplate">
  <ng-container [ngTemplateOutlet]="iconTemplate"></ng-container>
</ng-container>

foo.component.html

<foo-header [iconTemplate]="iconRef"></foo-header>
<ng-template #iconRef>
  <i-chevron-down></i-foo-icon>
</ng-template>

Another approach would be to directly transclude the icon markup into the component:

@Component({
  selector: 'foo-header'
})
export class ContentHeaderComponent {}

content-header.component.html

<ng-content select="[header-icon]"></ng-content>

foo.component.html

<foo-header>
  <i-chevron-down header-icon></i-foo-icon>
</foo-header>

You can read about these approaches and their pros/cons in this article.

Upvotes: 3

jo_va
jo_va

Reputation: 13963

It is not possible to dynamically create a selector of an angular component in angular, since Angular has to compile that element. You could do it for web components however, by compiling your angular component to angular elements, and then dynamically insert those web components in the DOM.

Upvotes: 0

Related Questions