碎碎念:最开始看到ng-template是在使用ng-zorro的时候,随着使用的越来越多,所有想系统的学习一下,能在以后的项目中灵活运用,有问题的地方,欢迎大家指正~~~~!
前置知识点:
1:ViewContainerRef:用于表示一个视图容器,可添加一个或多个视图。主要作用是创建和管理内嵌视图或组件视图。
可能涉及到的方法:clear()销毁本容器内的所有视图。createEmbeddedView()实例化一个内嵌视图,并把它插入到该容器中。
2:TemplateRef:用于表示内嵌的template模板元素(一组html元素)。通过TemplateRef实例,我们可以方便创建内嵌试图(EmbeddedView),且可以轻松访问到通过ElementRef封装后的nativeElement。需要注意的是组件视图的template模板元素,经过渲染后被替换成comment元素。
3:comment元素:表示不可见的注释,防止所包含的文本或html的源码被浏览器解析和显示。
1:定义
是一个angular元素,它不会直接展示在页面上,需要通过结构化指令将内容渲染到页面上。
我们常用的结构化指令,如*ngIf和*ngFor,其中*是一个语法糖,解开之后会变成ng-template标签
ngIf
<div *ngIf="hero">{
{
hero.name}}<div>
解析以后:ngIf变成属性型指令,并被绑定到ng-template上面,同时ngIf的宿主元素被ng-template包裹。
<ng-template [ngIf]="hero">
<div>{
{
hero.name}}<div>
</ng-template>
2:使用
写了一个简单的结构指令,类似于ngIf
<div *appTpl="showTpl;let txt=title;let name">
<b>{
{
txt}}({
{
name}})</b>
啦啦啦,我是卖报小行家
</div>
//ts部分:
showTpl = true;
tpl.directive.ts
import {
Directive, TemplateRef,ViewContainerRef,Input} from '@angular/core';
@Directive({
selector: '[appTpl]'
})
export class TplDirective {
constructor(
private templateRef:TemplateRef<any>,
private viewContainerRef:ViewContainerRef) {
}
@Input() set appTpl(bol:boolean) {
if(bol){
this.viewContainerRef.createEmbeddedView(this.templateRef,{
$implicit:'我是默认的',title:'卖报歌'});
}else{
this.viewContainerRef.clear();
}
}
}
3:扩展:
ngTemplateOutlet:
结构化指令。将提前准备好的TemplateRef(一组html元素)插入到一个内嵌视图。可以通过设置ngTemplateOutletContext来给EmbeddedViewRef附加一个上下文对象,ngTemplateOutletContext是一个对象,该对象中的key可以在模板中使用let语句进行绑定。
ngTemplateOutlet可以绑定到任何元素上。
<ng-container *ngTemplateOutlet="myTpl;context:{title:'儿歌'}"></ng-container>
<ng-template #myTpl let-title="title">
<h2>{
{
title}}</h2>
<p>我有一头小毛驴</p>
</ng-template>
或者
<ng-container [ngTemplateOutlet]="myTpl" [ngTemplateOutletContext]="{title:'儿歌'}"></ng-container>
使用:自定义标题或者页脚时,可以动态的向指定的组件传入一些内容,组件会把他们插入指定位置。
举个例子
//子组件
<ng-container *ngTemplateOutlet="myTpl;context:{txt:'传递给父元素的东西'}"></ng-container>
@Input('extra') myTpl!:TemplateRef<any>;
//父组件
<ng-test-child [extra]="myTpl"></ng-test-child>
<ng-template #myTpl let-txt="txt">
<div>传递给子组件的代码片段{
{
txt}}</div>
</ng-template>
在上述例子中,传递了templateRef实例,给子组件,子组件通过ngTemplateOutlet和Input接收,同时通过ngTemplateOutletContext传递参数展示在父组件的ng-template上。
综上不难看出,其实使用*ngTemplateOutlet实现的效果和createEmbeddedView效果相同。