javascript ngAfterContentInit和ngAfterContentChecked的正确约定是什么

pb3skfrl  于 2023-04-04  发布在  Java
关注(0)|答案(2)|浏览(166)

我创建了一个演示项目: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文档说了下面的事情:
一个三个三个一个
我无法找到关于上述观察的具体细节。

ogq8wdun

ogq8wdun1#

我试着给你总结一下:
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);
  }

看看我写的这个小demo:Stackblitz

qpgpyjmq

qpgpyjmq2#

第一次调用ContentHostComponentngAfterContentCheckedContentViewComponent视图还没有完成初始化(只有内容被投影),这是它返回空段落的原因。第二次调用ContentHostComponentngAfterContentChecked,这是在ContentViewComponent视图被初始化和检查之后。

相关问题