ng-content、ng-template、ng-container使用及区别

本文主要介绍了Angular中的ng-content、ng-template和ng-container。详细阐述了ng-content的简单投射、针对性投射及ngProjectAs属性;说明了ng-template用于定义模板渲染HTML;介绍了ng-container是特殊tag,不影响页面布局。还对比了三者区别,并给出学习地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、ng-content

1.1基础组件及结构

app.component.ts
father-component.ts

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

@Component({
  selector: 'app-father-component',
  templateUrl: './father-component.component.html',
  styleUrls: ['./father-component.component.css']
})
export class FatherComponentComponent implements OnInit {
  constructor() { }

  ngOnInit(): void {
  }

}

father-component.html

 <div class="demo">
    <h2>
      一个简单的组件
    </h2>
    </div>

father-component.css

.demo {
	padding: 10px;
	border: 2px solid red;	
}
h2 {
    margin: 0;
    color: #262626;
}

此时我们引用该组件,就会呈现该组件解析之后的内容:

<app-father-component></app-father-component>

在这里插入图片描述
如果说这个组件能够接受外部投射进来的内容,也就是说组件最终呈现的内容不仅仅是本身定义的那些,那该怎么做呢?这时就要请出本文的主角 ng-content

1.2简单投射

先修改father-component.html和father-component.css
father-component.html:

<div class="demo">
    <h2>
      一个简单的组件
    </h2>
    <div class="content">
      <ng-content></ng-content>
    </div>
</div>

father-component.css:

.demo {
	padding: 10px;
	border: 2px solid red;	
}
h2 {
    margin: 0;
    color: #262626;
}
.content {
    padding: 10px;
    margin-top: 10px;
    line-height: 20px;
    color: #FFFFFF;
    background-color: #de7d28;
}

为了效果展示特意将 所在的容器背景色定义为橙色。
这时我们在引用该组件时可以从外部投射内容,外部内容将在橙色区域显示:

<app-father-component>
    外部嵌入的内容
</app-father-component>

在这里插入图片描述

1.3 针对性性投射

如果同时存在几个 ,那外部内容将如何进行投射呢?
我们先看个示例,为了区别,我再新增一个蓝色区域的 ,修改后的father-component.html和 father-component.css 如下:

demo.component.html:

<div class="demo">
    <h2>
      一个简单的组件
    </h2>
    <div class="content">
      <ng-content></ng-content>
    </div>
    <div class="content blue">
      <ng-content></ng-content>
    </div>
</div>

father-component.css

.demo {
	padding: 10px;
	border: 2px solid red;	
}
h2 {
    margin: 0;
    color: #262626;
}
.content {
    padding: 10px;
    margin-top: 10px;
    line-height: 20px;
    color: #FFFFFF;
    background-color: #de7d28;
}
.blue {
    background-color: blue;
}

引用组件

<app-father-component>
    外部嵌入的内容
</app-father-component>

此时,我们将看到外部内容投射到了蓝色区域:
在这里插入图片描述
当然,如果你将橙色区域代码放在蓝色区域代码的后面,那么外部内容就会投射到橙色区域:

<div class="demo">
    <h2>
      一个简单的组件
    </h2>
    <div class="content blue">
      <ng-content ></ng-content>
    </div>
    <div class="content">
      <ng-content></ng-content>
    </div>
</div>

在这里插入图片描述
所以从上面的示例我们可以看出,如果同时存在简单的 ,那么外部内容将投射在组件模板最后的那个 中。

那么知道这个问题,我们可能会想,能不能将外部内容有针对性的投射相应的 中呢?答案显然是可以的。

为了处理这个问题, 支持一个 select 属性,可以让你在特定的地方投射具体的内容。该属性支持 CSS 选择器(标签选择器、类选择器、属性选择器、…)来匹配你想要的内容。如果 ng-content 上没有设置 select 属性,它将接收全部内容,或接收不匹配任何其他 ng-content 元素的内容。
修改后的father-component.html和 father-component.css 如下:

demo.component.html:

<div class="demo">
    <h2>
      一个简单的组件
    </h2>
    <div class="content">
      <ng-content></ng-content>
    </div>
    <div class="content blue">
      <ng-content select="header"></ng-content>
    </div>
    <div class="content red">
      <ng-content select=".demo1"></ng-content>
    </div>
    <div class="content green">
      <ng-content select="[name=demo2]"></ng-content>
    </div>
  
</div>

father-component.css :

.demo {
	padding: 10px;
	border: 2px solid red;	
}
h2 {
    margin: 0;
    color: #262626;
}
.content {
    padding: 10px;
    margin-top: 10px;
    line-height: 20px;
    color: #FFFFFF;
    background-color: #de7d28;
}
.blue {
    background-color: blue;
}
.red {
    background-color: red;
}
.green {
    background-color: green;
}

组件引用:

<app-father-component>
   开始, 外部嵌入的内容
   <header>
       header标签,外部嵌入的内容
    </header>
    <div class="demo1">
        我是外部嵌入的内容,我所在div的class"demo1"
    </div>
    <div name="demo2">
        我是外部嵌入的内容demo,我所在div的属性name为"demo2"
    </div>
    结束
</app-father-component>

在这里插入图片描述

1.4ngProjectAs

现在我们知道通过 ng-content 的 select 属性可以指定外部内容投射到指定的 中。

而要能正确的根据 select 属性投射内容,有个限制就是,只能直接子节点
那如果不是作为直接子节点,会是什么情况呢?我们简单修改下引用 father-component 组件的代码,将 标签header 放在一个div中,修改如下:
引用app-component.html:

<app-father-component>
   开始, 外部嵌入的内容
   <div>
    <header>
        header标签,外部嵌入的内容
     </header>
   </div>
 
    <div class="demo1">
        我是外部嵌入的内容,我所在div的class"demo1"
    </div>
    <div name="demo2">
        我是外部嵌入的内容demo,我所在div的属性name为"demo2"
    </div>
    结束
</app-father-component>

在这里插入图片描述
此时,我们看到 标签 header 那部分内容不再投射到蓝色区域中了,而是投射到橙色区域中了。原因就是 无法匹配到之前的 标签 header,故而将这部分内容投射到了橙色区域的 中了。

为了解决这个问题,我们必须使用 ngProjectAs 属性,它可以应用于任何元素上。具体如下:

 <app-father-component>
    开始, 外部嵌入的内容
    <div ngProjectAs="header">
        <header>
            header标签,外部嵌入的内容
         </header>
    </div>
    <div ngProjectAs=".demo1">
        <div class="demo1">
            我是外部嵌入的内容,我所在div的class"demo1"
        </div>
    </div>
    <div ngProjectAs="[name=demo2]">
        <div name="demo2">
            我是外部嵌入的内容demo,我所在div的属性name为"demo2"
        </div>
    </div>
     结束
 </app-father-component>

在这里插入图片描述

二、ng-template

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

<!-- 通过ngIf结构型指令显示ng-template的内容 -->
<div class="lessons-list" *ngIf="condition else elseTemplate">
    判断条件为真
</div>
<ng-template #elseTemplate>
    <div>判断条件为假</div>
</ng-template>

扩张:Angular中createEmbeddedView和createComponent之间的区别是什么
createEmbeddedView

三、ng-container

ng-container既不是一个Component,也不是一个Directive,只是单纯的一个特殊tag。ng-container可以直接包裹任何元素,包括文本,但本身不会生成元素标签,也不会影响页面样式和布局。包裹的内容,如果不通过其他指令控制,会直接渲染到页面中。

四、区别

ng-content: ng-content是内容映射指令(也叫内容嵌入),相当于vue中的slot内容分发,内容映射指的是在组件中嵌入模板代码,方便定制可复用的组件,很好地扩充组件的功能,方便代码的复用.
ng-template :使用 * 语法糖的结构指令,最终都会转换为 或 模板指令,模板内的内容如果不进行处理,是不会在页面中显示的。
ng-container:是一个逻辑容器,可用于对节点进行分组,但不作为 DOM 树中的节点,它将被渲染为 HTML中的 comment 元素,它可用于避免添加额外的元素来使用结构指令。

五、学习地址

ng-template、ng-content、ng-container
angular之ng-container 、ng-template、ng-content的使用
ng-container使用
g-template、ng-content、ng-container使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值