Wrap content in children in a dynamic parent tag

What i want to do

I want to create a reusable Angular 2 component that can appear as a <a /> tag or a <input /> depending on the input to the component named type . I want the button component to accept child content elements that will display as the button label.

To illustrate: the Angular pattern that invokes my button component as follows: <button>Hello</button> should display as <a>Hello</a> in the DOM. However, if the type="submit" property is set (for example, <button type="submit>Hello</button> ), the output in the DOM should be <input type="submit">Hello</input> .

For further clarification, if I were using React, I could create a [overly simplified version] of this component with:

 const Button = ({ type, children }) => type === "submit" ? <input type="submit">{children}</input> : <a>{children}</a> 

Where am i stuck

Creating an Angular component that displays children with content using <ng-content /> was relatively easy. However, I cannot yet display these children inside a dynamically selected tag - either <a /> or <input /> depending on the value of the type property.

What i tried

At first I tried to use <ng-content /> inside the ngIf or ngSwitch , only to find out that <ng-content /> can appear no more than once in any given template (unless it is qualified with a selector). However, I want to display all the child elements of the content, so the selectors do not help.

I keep finding links to DynamicComponentLoader, but this seems to be out of date.

I saw a ContentChildren decorator that will allow my button component to access the content that is passed to the children, but I don’t know how to take these children later and enter them into my component template.

I came across NgTemplateOutlet , which seems to help me switch between two completely different templates (one with <a /> and the <input /> ). However, this is marked as "Experimental" and Im does not understand the use.

Any help would be greatly appreciated!

+5
source share
1 answer
 @Component({ selector: 'adapting-button', template: ` <a *ngIf="type !== "submit">{{value}}</a> <input *ngIf="type === "submit" type="submit" [value]="value"> `, }) export class AdaptingButtonComponent { @Input() type: any; @Input() value: any; } @Component({ selector: 'app-root', templateUrl: ` <adapting-button [type]="'submit'" [value]="Hello"></adapting-button> `, }) export class AppComponent { title = 'app works!'; } 
+1
source

Source: https://habr.com/ru/post/1262328/


All Articles