使用投影来创建灵活的可复用性组件
投影分为三种:
单插槽内容投影,使用这种投影,组件可以从单一来源接受内容
多插槽内容投影,使用这种投影,组件可以从多个来源接受内容
有条件的内容投影,使用条件内容投影的组件必须在符合条件时才能接受内容
ng-content 元素只是一个占位符,它不会创建真正的dom元素,ng-content 上的自定义属性将会被忽略
单插槽内容投影:
//内容投影组件模板
<p>单插槽内容投影:</p>
<app-one-content-projection>
<p>单插槽内容投影</p>
</app-one-content-projection>
//使用内容投影组件模板
<h2>单插槽内容投影 组件</h2>
<ng-content></ng-content>
多插槽内容投影
//内容投影组件模板
<h2>Multi-slot content projection</h2>
Default:
<ng-content></ng-content>
Question:
<ng-content select="[question]"></ng-content>
//使用内容投影组件模板
<p>多插槽内容投影</p>
<app-multislot-content>
<p>没有select选择器</p>
<p>111</p>
<p question> 问题? 这里是带select选择器的</p>
</app-multislot-content>
注:如果多插槽内容投影组件中包含 没有select的ng-content元素,则该实例将接受所有不符合select选择器的投影组件
如上述:
<p>没有select选择器</p><p>111</p>
都会投影到
Default:
<ng-content></ng-content>
有条件的内容投影
不推荐使用ng-content元素 使用ng-content元素 因为组件的使用者只要提供了内容,即使从未定义过ng-content或者在ngif下,内容也会初始化
需要新建一个指令以将 标记为组件内容。借助这个 TemplateRef,组件可以使用 ngTemplateOutlet指令或ViewContainerRef.createEmbeddedView()方法来渲染所引用的内容。
@Directive({
selector: '[appConditionally]'
})
export class ConditionallyDirective{
constructor(public templateRef: TemplateRef<unknown>) { }
}
//使用投影组件模板
<p>有条件的内容投影</p>
<app-if-content>
<ng-template appConditionally>
<p>有条件的内容投影 内容部分</p>
</ng-template>
</app-if-content>
//投影组件模板
<div>
<p>有条件的组件投影:</p>
<ng-container *ngIf="status">
<ng-container [ngTemplateOutlet]="content.templateRef"></ng-container>
</ng-container>
</div>
//投影组件 ts
status = false;
@ContentChild(ConditionallyDirective) content!: ConditionallyDirective;
constructor() {
interval(1000).subscribe(res => this.status = !this.status)
}