POV
POV

Reputation: 12005

How to reuse template HTML block in Angular?

Lets suppose we have html block in file:

<div id="text">Text</div>

How can I reuse this html code below in the same file, I mean something like this:

<re-use id="text"></re-use>

Is it possible?

Upvotes: 130

Views: 76622

Answers (5)

Adeel Shekhani
Adeel Shekhani

Reputation: 1105

I might be late to the party. There are some answers though, but I couldn't achieve it with what is described in above answers I still felt that someone might need a bit of direction.

Key points that are not defined in any of the answers clearly.

  1. Consider you have a template which is binding some values in it. So you have to attach a context object in order make template binding work.
<ng-template #invoicesTemplate let-paymentInvoices="paymentInvoices">
    ...
</ng-template>

note that let-anyVariableName for template and "paymentInvoices" is the class variable that you are passing.

in usage

<ng-template *ngTemplateOutlet="invoicesTemplate; context: {paymentInvoices : paymentInvoices} "></ng-template>
  1. You have to define template first and then use it anywhere you want to. Just think of a function declaration. But until unless you don't call function it wont have any affect.

Overall code declaration of template

<ng-template #invoicesTemplate let-paymentInvoices="paymentInvoices">
  <div class="row">
    <div class="col-sm-12">
      <div class="tags-group">
        <div class="tag" *ngFor="let invoice of paymentInvoices">
          <div class="tag-body">
            <span>{{invoice.invoiceNo }}</span>
            <span (click)="removeInvoice(invoice)"><i title="remove" >x</i></span>
          </div>
        </div>
      </div>
    </div>
  </div>
</ng-template>

calling/usage

<ng-template *ngTemplateOutlet="invoicesTemplate; context: {paymentInvoices : paymentInvoices} "></ng-template>

You can use it any number of times you want.

Upvotes: 36

Divek John
Divek John

Reputation: 755

This can be done with help of a custom directive in a more standard way.

In directive.ts

import { Directive } from '@angular/core';
@Directive({
  selector: '[cardItem]'
})
export class CardItemDirective {}

In component.ts

import { Component, ContentChild, Input, TemplateRef } from '@angular/core';
import { CardItemDirective } from './card-item.directive';
import { ListItemDirective } from './list-item.directive';

@Component({
  selector: 'card-or-list-view',
  templateUrl: './card-or-list-view.component.html'
})
export class CardOrListViewComponent {

  @Input() items: any[] = [];

  @Input() mode: 'card' | 'list' = 'card';

  // Read in our structural directives as TemplateRefs
  @ContentChild(CardItemDirective, {read: TemplateRef}) cardItemTemplate;
  @ContentChild(ListItemDirective, {read: TemplateRef}) listItemTemplate;

}

in component.html

<ng-container [ngSwitch]="mode">
<ng-container *ngSwitchCase="'card'">
  <ng-container *ngFor="let item of items">
    <ng-container *ngTemplateOutlet="cardItemTemplate"></ng-container>
  </ng-container>
</ng-container>
<ul *ngSwitchCase="'list'">
  <li *ngFor="let item of items">
    <ng-container *ngTemplateOutlet="listItemTemplate"></ng-container>
  </li>
</ul>
</ng-container> 

You can find more details in this link

Upvotes: 1

Mart
Mart

Reputation: 5788

Creating a new component is the most common way, but sometimes you only need some local markup to be repeated and ng-template allows that.

What is interesting is that it's even possible to pass a context to be able to use data binding:

<ng-template #tplPerson let-person>
    <span class="person-id">{{person.id}}</span>
    <span class="person-alias" *ngIf="!!person.alias">"{{person.alias}}"</span>
    <span class="person-name">{{person.name}}</span>
</ng-template>

let-person without a value defines the context variable person with the value set to $implicit when instantiating the template:

<ng-template *ngTemplateOutlet="tplPerson; context: {$implicit: thePerson}"></ng-template>

See more options in the documentation of NgTemplateOutlet.

Upvotes: 94

Ramya S
Ramya S

Reputation: 3094

I think you wanted to reuse the same html block again. If i understand you correctly, below code should help

<ng-template #MsgRef >
        {{ mycontent }}
</ng-template>

To reuse above block in the same template,

 <ng-template [ngTemplateOutlet]="MsgRef"></ng-template> //reuse any number of times

Upvotes: 236

Gentle Brute
Gentle Brute

Reputation: 142

You can create a custom html-tag using angular then import that component in your module that wants to use those custom-tags. Then you'll be allowed to use the same tag in your html page. Created a small example that can maybe help you understand ?

https://stackblitz.com/edit/angular-stackoverflow

Upvotes: 8

Related Questions