Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2: How to pass down a template through a component property?

How to pass down a template through a component property in angular 2?

I've only made the first steps:

@Component({
    selector: 'tab',
    template: `<div>#!HERE GOES THE HEADER TEMPLATE!#
                <ng-content></ng-content>
              </div>`
})
export class Tab {
    @Input() title: string;
    @Input() headerTemplate:string;
    ...

That could be used something like this:

<tab [title]="'Some Title'" [header-template]="'<p>{{title}}</p>'">Some Content</tab>

That should render:

<div><p>Some Title</p>Some Content</div>

At this point I'm stuck.

like image 627
Joao Rodrigues Avatar asked Oct 23 '15 10:10

Joao Rodrigues


People also ask

How do I pass a template reference variable in component?

To get started using template reference variables, simply create a new Angular component or visit an existing one. To create a template reference variable, locate the HTML element that you want to reference and then tag it like so: #myVarName .

How do you pass a prop in component Angular?

Answer: You can't. Props aren't a thing in Angular.

How do I pass a ng template?

In order to have a template rendered in that container, we use the *ngTemplateOutlet to pass a reference to an existing template, such as the one we created earlier. We use @Input to pass a TemplateRef to our component.

Which data binding can pass data from a template to a component?

There are two ways to pass data into a component, with 'property binding' and 'event binding'.


3 Answers

Though this question is very old, there are much better solutions available. There is no need to pass a string as a template - that is very limiting. You can create an element and get its 'TemplateRef' and send that to a component which takes TemplateRef as input. A component can take any number of TemplateRefs as input actually, and you can inject those templates in any number of places.

Note that the 'template' element is deprecated, and the 'ng-template' element should be used in all cases.

So, in a parent component -

<ng-template #thisTemplate>You Can put anything here, including other components</ng-template>

 <tab [template]="thisTemplate"></tab>

Then in the tabs component from the OP

 import { Component, Input, TemplateRef, ViewChild, ViewContainerRef } from '@angular/core'

.... somehwere in its template ....

 <div #viewcontainer></div>

Down in the component :

 @ViewChild('viewcontainer',{read:ViewContainerRef}) viewcontainer : ViewContainerRef;

 @Input() template : TemplateRef<any>;


 ngAfterViewInit() { 
     this.viewcontainer.createEmbeddedView(this.template);
 }
like image 109
diopside Avatar answered Sep 22 '22 02:09

diopside


An method similar to diopside’s but using a container element for projection in the template rather than programmatically:

parent.component.html

<app-child [template]=“templateRef”></app-child>
<ng-template #templateRef>
  <p>hello, from defined in parent</p>
</ng-template>

child.component.ts

<ng-container *ngTemplateOutlet=“templateRef”></ng-container>
like image 24
1252748 Avatar answered Sep 20 '22 02:09

1252748


After some research, I’ve checked that someone already has an elegant solution for this question. At https://github.com/valor-software/ngx-bootstrap/blob/development/src/tabs the tab component can receive a template to tab heading. Great work!

Checking the code the solution relies on two directives, a tab specific one: TabHeading and a generic one:NgTransclude)

As presented there, the component can be created passing a template:

<tab>
    <template tab-heading>Tab 2</template>
    Tab 2 content
</tab>

If someone can give a better explanation of that implementation, please do.

like image 29
Joao Rodrigues Avatar answered Sep 19 '22 02:09

Joao Rodrigues