如何重用模板 HTML 块的角度?

让我们假设文件中有 html 块:

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

如何在同一个文件中重用下面的 html 代码,我的意思是这样的:

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

有可能吗?

51350 次浏览

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

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

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.

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

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.