ChatGPT解决这个技术问题 Extra ChatGPT

Angular2的ngOnInit和ngAfterViewInit有什么区别?

我无法理解 ngOnInitngAfterViewInit 之间的区别。

我发现它们之间的唯一区别是 @ViewChild。根据下面的代码,它们中的elementRef.nativeElement是相同的。

我们应该使用ngAfterViewInit什么场景?

@Component({
  selector: 'my-child-view',
  template: `
  <div id="my-child-view-id">{{hero}}</div>
  `
})
export class ChildViewComponent {
  @Input() hero: string = 'Jack';
}

//////////////////////
@Component({
  selector: 'after-view',
  template: `
    <div id="after-view-id">-- child view begins --</div>
      <my-child-view [hero]="heroName"></my-child-view>
    <div>-- child view ends --</div>`
    + `
    <p *ngIf="comment" class="comment">
      {{comment}}
    </p>
  `
})
export class AfterViewComponent implements AfterViewInit, OnInit {
  private prevHero = '';
  public heroName = 'Tom';
  public comment = '';

  // Query for a VIEW child of type `ChildViewComponent`
  @ViewChild(ChildViewComponent) viewChild: ChildViewComponent;

  constructor(private logger: LoggerService, private elementRef: ElementRef) {
  }

  ngOnInit() {
    console.log('OnInit');
    console.log(this.elementRef.nativeElement.querySelector('#my-child-view-id'));
    console.log(this.elementRef.nativeElement.querySelector('#after-view-id'));
    console.log(this.viewChild);
    console.log(this.elementRef.nativeElement.querySelector('p'));
  }

  ngAfterViewInit() {
    console.log('AfterViewInit');
    console.log(this.elementRef.nativeElement.querySelector('#my-child-view-id'));
    console.log(this.elementRef.nativeElement.querySelector('#after-view-id'));
    console.log(this.viewChild);
    console.log(this.elementRef.nativeElement.querySelector('p'));
  }
}

G
Günter Zöchbauer

在第一次调用 ngOnChanges() 之后调用 ngOnInit()。每次更改检测更新输入时都会调用 ngOnChanges()

ngAfterViewInit() 在最初呈现视图后调用。这就是 @ViewChild() 依赖它的原因。在呈现之前,您无法访问视图成员。


当你说渲染时,你的意思是它出现在屏幕上吗? (或发送以呈现在屏幕上)
当它被添加到 DOM 中时。如果您设置 display: hidden,它会一直渲染,但在屏幕上不可见。但是,如果您使用浏览器开发工具调查 DOM,您将能够看到标记。
在呈现之前您无法访问视图成员” - 那么您如何解释 ViewChild (vc) 在 onNgInit 上可用? plnkr.co/edit/AzhRe6bjnuPLKJWEJGwp?p=preview,你能解释一下吗?
@Royi 我无法在我的手机上打开你的 Plunker,它需要几天才能回到我的电脑上。 ngOnInit 中已提供静态添加的元素。如果您有由 *ngFor 从数据传递到 @Input 呈现的内容,则此内容在 ngOnInit 中尚不可用
非常感谢您的回复。这正是场景。所以我想这就是它。 i.imgur.com/Vbajl4F.jpg 。享受你的假期。
P
Peter

ngOnInit() 在第一次检查指令的数据绑定属性之后,并且在检查其任何子项之前立即调用。当指令被实例化时,它只被调用一次。

ngAfterViewInit() 在创建组件视图及其子视图后调用。它是一个生命周期钩子,在组件的视图完全初始化后调用。


“在组件的视图完全初始化之后”表明这是在 ngOnInit 之后,这是不正确的(可以在 ngOnInit 之前/期间调用 ngAfterViewInit)
S
STEEL

内容是作为孩子传递的。 View 是当前组件的模板。

视图在内容之前初始化,因此 ngAfterViewInit()ngAfterContentInit() 之前被调用。

** 第一次检查子指令(或组件)的绑定时调用 ngAfterViewInit()。因此,它非常适合使用 Angular 2 组件访问和操作 DOM。正如前面提到的@Günter Zöchbauer 是正确的 @ViewChild() 因此在其中运行良好。

例子:

@Component({
    selector: 'widget-three',
    template: `<input #input1 type="text">`
})
export class WidgetThree{
    @ViewChild('input1') input1;

    constructor(private renderer:Renderer){}

    ngAfterViewInit(){
        this.renderer.invokeElementMethod(
            this.input1.nativeElement,
            'focus',
            []
        )
    }
}

我认为你在这里错了。 ngAfterViewInit() 仅在 ngAfterContentChecked() 之后执行,而 ngAfterContentChecked() 仅在 ngAfterContentInit() 和每个后续 ngDoCheck() 之后执行。有关更多详细信息,请参阅角度生命周期挂钩详细信息 angular.io/guide/lifecycle-hooks