用法类似于ViewChild,获取投影中的组件、指令和dom元素,类似于vue中的具名插槽和匿名插槽
import { Component, Input, TemplateRef } from '@angular/core';
@Component({
selector: 'app-shadow',
template: `
<div class="shadow">
<div class="head">
<ng-content select=".head"></ng-content>
</div>
<div class="body">
<ng-content select="[attr]"></ng-content>
<ng-content select="article"></ng-content>
<ng-content></ng-content>
</div>
<div class="foot">
<ng-content select=".foot"></ng-content>
</div>
</div>`
})
export class ShadowComponent {}
- 调用ShadowComponent
import { Component, Input } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-shadow [visible]="true">
<div class="head">这是head的投影</div>
<div attr>这是attr的投影内容</div>
<article>这是article的投影内容</article>
<b style="color: #007bff">这是默认的投影内容</b>
<div class="foot">这是foot的投影</div>
</app-shadow>
`
})
export class AppComponent {}
获取投影中的组件
- ContentChild
import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core';
@Component({
selector: 'app-content-child-panel',
templateUrl: './content-child-panel.component.html'
})
export class ContentChildPanelComponent implements OnInit {
constructor() { }
ngOnInit(): void {}
alert() {
alert('aa');
}
}
@Component({
selector: 'app-content-child',
template: `
<div class="content-child-box">
<h2>这是content child组件</h2>
<div class="head" style="border: 1px solid; margin: 10px 0;">
<ng-content select=".head"></ng-content>
</div>
<ng-content></ng-content>
</div>
`,
styles: []
})
export class ContentChildComponent implements AfterViewInit {
// 无法获取dom元素
// @ContentChild('.head', { static: true }) private headEl: ElementRef;
// @ContentChild('list', { static: true }) private listEl: ElementRef;
@ContentChild(ContentChildPanelComponent, { static: true }) private panel: ContentChildPanelComponent;
constructor() { }
ngAfterViewInit(): void {
this.panel.alert();
}
}
- 调用ContentChildComponent
<app-content-child>
<div class="head">
这是头部
</div>
<app-content-child-panel></app-content-child-panel>
<ul #list>
<li>aaa</li>
<li>bbb</li>
</ul>
</app-content-child>
- ContentChildren
用法类似ViewChildren, 批量获取投影中到组件或指令
<app-content-child>
<div class="head">
这是头部
<app-content-child-panel></app-content-child-panel>
</div>
<app-content-child-panel></app-content-child-panel>
<app-content-child-panel></app-content-child-panel>
<ul #list>
<li>aaa</li>
<li>bbb</li>
</ul>
</app-content-child>
export class ContentChildComponent implements AfterViewInit {
@ContentChildren(ContentChildPanelComponent) private panels: QueryList<ContentChildPanelComponent>;
constructor() { }
ngAfterViewInit(): void {
console.log(this.panels); // 只有两个结果
}
}
这里只能拿到两个panels,默认只寻找直属的panel 而.head里的panel组件嵌套了一层div,并非直属
想要拿到所有层级的panel组件,需要开启
descendants
属性
@ContentChildren(ContentChildPanelComponent, { descendants: true }) private panels: QueryList;
网友评论