angular中的ng-content、ng-template、ng-container的用法和Vue的插槽功能

119 阅读1分钟

1.ng-content 元素指定了在组件模板中投影内容的位置 个人感觉和vue的插槽功能差不多

代码如下 inner-container和outer-container是两个组件在另一个页面index使用
<!-- outer-container 组件 -->
<div>
  <p>outer-container works!</p>
  <ng-content></ng-content>
</div>
<!-- inner-container 组件 -->
<div>
  <p>inner-container works!</p>
</div>
<!-- index 页面上显示 -->
<app-outer-container>
    <app-inner-container></app-inner-container> <!-- ng-content -->
</app-outer-container>
这里看到inner容器在outer容器的ng-content处显示出来了

image.png

多插槽内容投影 select=['名称']
<!-- outer-container 组件 -->
<div>
  <p>outer-container works!</p>
  <p>下面是默认content</p>
  <ng-content></ng-content>
  <p>下面是select为question的content</p>
  <ng-content select="[question]"></ng-content>
</div>
<!-- inner-container 组件 -->
<div>
  <p>inner-container works!</p>
</div>
<!-- index 页面上显示 -->
<app-outer-container>
    <app-inner-container question></app-inner-container> <!-- ng-content -->
</app-outer-container>

image.png

这里是vue的插槽 感觉实现功能还是很类似的
<!-- outer-container 组件 -->
<div class="outer">
 <FancyButton>
    <div>inner-container works!</div>
 	</FancyButton>
</div>

<!-- inner-container 组件 -->
<template>
  <div class="inner">
    <slot/> <!-- slot outlet -->
  </div>
</template>

image.png

2.ng-template和ng-container ng-template元素定义了一个默认不渲染的模板 ng-container相当于一个空元素

当total小于10的时候显示templete里的内容
<ng-container *ngIf="total >=10; else elseTemplate">
  total大于等于10
</ng-container>
<ng-template #elseTemplate>
  total小于10
</ng-template>

image.png

结合optTemplateOutlet渲染ng-template里的内容
<!-- outer-container 组件 -->
<div>
  <p>outer-container works!</p>
  <app-inner-container [optTemplateOutlet]="{'opt': demo}"></app-inner-container>
</div>
<ng-template #demo>
  这里是标签里的内容
</ng-template>
<!-- inner-container 组件 -->
<div>
  <p>inner-container works!</p>
  <ng-container *ngTemplateOutlet="optTemplateOutlet['opt'];"></ng-container>
</div>

// inner-container ts
@Input() public optTemplateOutlet!: {
    [key: string]: TemplateRef<{[key: string]: string}[]>
};
<!-- index 页面上显示 -->
<app-outer-container></app-outer-container>

image.png

结合optTemplateOutlet渲染ng-template里的内容 可以通过context将inner里的内容传递给outer
<!-- outer-container 组件 -->
<div>
  <p>outer-container works!</p>
  <app-inner-container [optTemplateOutlet]="{'opt': demo}"></app-inner-container>
</div>
<ng-template #demo let-data="message">
  这里是标签里的内容
  <p>{{data?.name}}</p>
</ng-template>
<!-- inner-container 组件 -->
<div>
  <p>inner-container works!</p>
  <ng-container *ngTemplateOutlet="optTemplateOutlet['opt']; context: {message: message}"></ng-container>
</div>
// inner-container ts
@Input() public optTemplateOutlet!: {
    [key: string]: TemplateRef<{[key: string]: string}[]>
};
public message: {[key: string]: string} = {name: '这里是通过context额外信息传递'};
<!-- index 页面上显示 -->
<app-outer-container></app-outer-container>

image.png