上次我们聊到了angular的插槽,主要利用了特殊标签ng-content。
新建几个component:
ng g component components/father
ng g component components/child
ng g component components/other
插槽只需在模板文件声明即可。
father.component.html:
<app-child>
<app-other></app-other>
</app-child>
child.component.html:
<ng-content select="app-other"></ng-content>
通过ng-content可以获取app-other组件的视图内容,如果我还想要获取插槽中包含的组件的内部信息呢?比如获取app-other组件中的属性和方法?
这时我们可以利用contentChild来解决。
contentChild
child.component.ts:
import { Component, OnInit, ContentChild} from '@angular/core';
import { OtherComponent } from '../other/other.component';//引入other组件
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.scss']
})
export class ChildComponent implements OnInit {
@ContentChild(OtherComponent) other:OtherComponent;//属性装饰器
constructor() { }
ngOnInit(): void {
}
ngAfterContentInit(): void {
//ngAfterContentInit()是与投影内容初始化有关
console.log(this.other.username);
this.other.sayHello();
}
}
contentChildren
如果是一组元素,我们可以用contentChildren。
father.component.html:
<app-child>
<app-other [role]="'admin'"></app-other>
<app-other [role]="'common'"></app-other>
<app-other [role]="'user'"></app-other>
</app-child>
child.component.html:
<ng-content select="app-other"></ng-content>
child组件仍旧用ng-content占位。
child.component.ts:
import { Component, OnInit, ContentChildren,QueryList} from '@angular/core';
import { OtherComponent } from '../other/other.component';//引入other组件
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.scss']
})
export class ChildComponent implements OnInit {
@ContentChildren(OtherComponent) others:QueryList<OtherComponent>;//获取多个OtherComponent
constructor() { }
ngOnInit(): void {
}
ngAfterContentInit(): void {
//ngAfterContentInit()是与投影内容初始化有关
this.others.forEach(item=>{
console.log(item.role) //遍历一组元素
item.sayRole();//执行每个组件下面的方法
})
}
}
other.component.ts:
import { Component, OnInit,Input } from '@angular/core';
@Component({
selector: 'app-other',
templateUrl: './other.component.html',
styleUrls: ['./other.component.scss']
})
export class OtherComponent implements OnInit {
@Input() role;
constructor() { }
ngOnInit(): void {
}
sayRole(){
console.log('当前角色:',this.role);
}
}
总结
contentChild和contentChildren都是获取插槽内容的,有人也称其为投影,说的都是一个东西,就是嵌入在组件中间的那部分内容。
这部分嵌入内容,如果有component组件的话,如果只是获取组件渲染出来的视图那就用ng-content占位即可;如果要获取组件内部的信息就要用到contentChild,而如果是包含了多个组件,那就要用到contentChildren。