一、ng-content


二、ng-container

ng-container是一个特殊的容器标签,不会产生真实的dom元素,所以在ng-container标签添加属性是无效的。

<div>
	<!-- 这里添加的类red不会起作用 -->
	<ng-container class="red"> 
		<h3>ng-container的使用</h3>
		<div>hello world!<div>
	</ng-container>
</div>

渲染的dom结构

<div>
	<h3>ng-container的使用</h3>
	<div>hello world!<div>
</div>

同时使用*ngIf*ngFor,会报错 error NG5002: Can’t have multiple template bindings on one element. Use only one attribute prefixed with *

<div *ngIf="item.isActive" *ngFor="let item of list;let key = index;">
	<div>{{key}}、{{item.name}}</div>
</div>

此时需要分开写,但是这样会生成两层div包裹内容。

<div *ngFor="let item of list;let key = index;">
    <div *ngIf="item.isActive">
        {{item.name}}
    </div>
</div>

所以ng-container便派上用场,此时是一层div包裹内容。当然也可以都换成ng-container,但是不能添加样式等属性(因为ng-container标签不会渲染dom,标签上的属性不会起作用),这块可根据实际开发场景决定。

<ng-container *ngFor="let item of list;let key = index;">
    <div *ngIf="item.isActive">
        {{item.name}}
    </div>
</ng-container>

ng-container一般用在结构化指令,如ngIf/ngSwitch/ngFor

<div [ngSwitch]="value">
    <ng-container *ngSwitchCase="0">Text 0</ng-container>
    <ng-container *ngSwitchCase="1">Text 1</ng-container>
    <ng-container *ngSwitchCase="2">Text 2</ng-container>
</div>

三、ng-template

ng-template用于定义模板渲染HTML。定义的模板不会直接显示出来,需要通过其他结构型指令(如 ngIf)或 templateRef 将模块内容渲染到页面中。

<!-- 内容不显示 -->
<ng-template>
	I am ng-template
</ng-template>

<!-- 内容会显示 -->
<ng-container>I am ng-container</ng-container>

1.使用ngIf指令显示对应的ng-template模板

<div *ngIf="isVisible;else hide;">某某内容</div>

<ng-template #hide>隐藏的内容</ng-template>

2.通过TemplateRefViewContainerRefng-template对应的元素显示出来

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

@Component({
  selector: 'app-animal',
  template: `
    <ng-template #hello>hello world</ng-template>
  `,
  styleUrls: ['./animal.component.less']
})
export class AnimalComponent implements OnInit {
 
  @ViewChild('hello', {static: true}) hello: TemplateRef<any>

  constructor(private view: ViewContainerRef) { }

  ngOnInit(): void {
    this.view.createEmbeddedView(this.hello)
  }

}

3.使用ngTemplateOutle指令显示对应的ng-template模板
此处参考

"*"的结构型指令是原结构型指令的语法糖,它会翻译成特定的ng-template结构。

<div *ngIf="isVisible as show">hello world/{{show}}</div>
<!-- 等同 -->
<ng-template [ngIf]="isVisible" let-show="ngIf">
	<div>hello world/{{show}}</div>
</ng-template>
<div *ngFor="let item of list as items;let key = index;trackBy: trackFn">
	{{index}}、{{item.name}}
</div>
<!-- 等同 -->
<ng-template ngFor [ngForOf]="list" let-key="index" let-item let-items="ngForOf" [ngForTrackBy]="trackFn">
	<div>{{index}}、{{item.name}}</div>
</ng-template>