ngAfterContentInit和ngaftercontentcheck的正确契约是什么?



我创建了一个演示项目:https://stackblitz.com/edit/angular-e6pqlb?file=src%2Fcontent-host%2Fcontent-host.component.ts

请打开上面的链接并检查控制台打印的值以理解我下面的观点。

所以,如果你检查src/main.html,内容投影被使用。

输入属性名为inputValueAppRootComponent提供到投影内容组件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方法将被调用。

这意味着段落内的内容应该NOT如果在ngAfterContentInit方法中访问,则为空。

这意味着,中的段落元素应该具有valuetestValue

但事实并非如此。段落加载空值

同样,第一次调用ngAfterContentChecked方法也会输出同样的内容。

这更让我困惑。因为我认为ngAfterContentChecked是在变更检测完成后调用的,并且DOM视图和组件类是同步的。

因此,在更改检测结束后,应该加载从AppRootComponent(意思是'testValue')接收的值作为输入的空段落。

但事实并非如此。

最后,当ngAfterContentChecked第二次调用时,段落被填满值.

那么,Angular在ngAfterContentInit和ngAfterContentChecked中的行为是怎样的呢?我的理解哪里出错了?Angular文档中说:
ngAfterContentInit() -->
Respond after Angular projects external content into the component's view, or into the view that a directive is in.
See details and example in Responding to changes in content in this document.
ngAfterContentChecked -->
Respond after Angular checks the content projected into the directive or component.
See details and example in Responding to projected content changes in this document.

我找不到以上观察的具体细节。

我试着给你总结一下:

AfterContentInit是一个只运行一次的钩子:当投影内容初始化时。

@Component({
selector: 'parent',
standalone: true,
template: '<ng-content></ng-content>',
})
class ParentComponent implements AfterContentInit {
@ContentChild(ChildComponent) content:any;
ngOnInit(): void {
console.log('Not init yet:', this.content);
}
ngAfterContentInit(): void {
console.log('content init:', this.content);
}
}

AfterContentChecked是一个钩子,它将在内容被检查后运行(大多数情况下它是在变更检测周期中)。

ngAfterContentChecked(): void {
console.log('child val: ', this.content.val);
}

检查我写的这个小演示:Stackblitz

第一次调用ContentHostComponentngAfterContentChecked,ContentViewComponent视图尚未完成初始化(仅投影内容),原因是它返回一个空段落。第二次调用ContentHostComponentngAfterContentChecked,这是在ContentViewComponent视图初始化和检查之后。

相关内容

  • 没有找到相关文章

最新更新