Какая разница между ngOnInit и ngAfterViewInit от Angular2?

Я не понимаю, в чем разница между ngOnInit и ngAfterViewInit.

Я нашел единственное различие между ними: @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'));
  }
}

Ответ 1

ngOnInit() вызывается после того, как ngOnChanges() был вызван в первый раз. ngOnChanges() вызывается каждый раз, когда входы обновляются с помощью обнаружения изменений.

ngAfterViewInit() вызывается после того, как представление первоначально отображается. Вот почему @ViewChild() зависит от этого. Вы не можете получить доступ к элементам просмотра до их рендеринга.

Ответ 2

ngOnInit() вызывается сразу после того, как свойства, привязанные к данным, были проверены в первый раз и до того, как был проверен любой из его дочерних элементов. Он вызывается только один раз, когда создается экземпляр директивы.

ngAfterViewInit() вызывается после представления компонента и его дочерних представлений. Его крючок жизненного цикла, который вызывается после представления компонента, полностью инициализирован.

Ответ 3

Содержание - это то, что передается как дети. Вид - это шаблон текущего компонента.

Представление инициализируется до того, как содержимое и ngAfterViewInit() вызывается до ngAfterContentInit().

** ngAfterViewInit() вызывается, когда привязки дочерних директив (или компонентов) были проверены в первый раз. Следовательно, он идеально подходит для доступа и управления DOM с помощью компонентов Angular 2. Как уже упоминалось выше, 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',
            []
        )
    }
}