我创建了一个演示项目:https://stackblitz.com/edit/angular-e6pqlb?file=src%2Fcontent-host%2Fcontent-host.component.ts
请打开上面的链接并检查控制台打印的值以理解我下面的观点。
因此,如果您检查src/main.html,则会使用内容投影。
名为inputValue的输入属性由AppRootComponent提供给投影内容组件ContentViewComponent。
<app-content-host>
<app-content-view #testContent [inputValue]="inputValue"></app-content-view>
</app-content-host>
投影组件ContentViewComponent在其模板中有一个简单的段落
<p>{{ inputValue }}</p>
我试图使用ContentChild和直接的DOM API来观察段落中的值。
export class ContentHostComponent implements AfterContentInit {
@ContentChild('testContent', { read: ElementRef }) contentChild: ElementRef;
ngAfterContentInit(): void {
console.log(document.body.innerHTML);
const innerHTML = this.contentChild.nativeElement.innerHTML;
console.log('inner HTML inside ngAfterContentInit : ', innerHTML);
}
ngAfterContentChecked(): void {
console.log(document.body.innerHTML);
const innerHTML = this.contentChild.nativeElement.innerHTML;
console.log('inner HTML inside ngAfterContentChecked : ', innerHTML);
}
}
我无法理解ngAfterContentInit和ngAfterContentChecked的行为。
我所理解的是:一旦投影的内容被完全呈现(即,改变检测运行并且DOM和组件类同步),则在ngAfterContentInit方法之后将被调用。
这意味着如果在ngAfterContentInit方法中访问,段落中的内容应该NOT为空。
这意味着,中的段落元素应该具有值testValue
但事实并非如此。段落加载了空值。
同样,第一个ngAfterContentChecked方法调用也会打印相同的内容。
这让我更困惑,因为我认为ngAfterContentChecked是在完成更改检测并且DOM视图和组件类同步之后调用的。
因此,在变化检测结束后,空段落应该加载从AppRootComponent接收的值作为输入(意味着'testValue')。
但事实并非如此。
最后,第二次调用ngAfterContentChecked时,Paragraph中会填入value。
那么,Angular在ngAfterContentInit和ngAfterContentChecked中的行为如何?我的理解错在哪里?Angular文档说了下面的事情:
一个三个三个一个
我无法找到关于上述观察的具体细节。
2条答案
按热度按时间ogq8wdun1#
我试着给你总结一下:
AfterContentInit
是一个只运行一次的钩子:当投影内容被初始化时。AfterContentChecked
是一个钩子,它将在内容被检查后运行(大多数情况下是在更改检测周期期间)。看看我写的这个小demo:Stackblitz
qpgpyjmq2#
第一次调用
ContentHostComponent
的ngAfterContentChecked
,ContentViewComponent
视图还没有完成初始化(只有内容被投影),这是它返回空段落的原因。第二次调用ContentHostComponent
的ngAfterContentChecked
,这是在ContentViewComponent
视图被初始化和检查之后。