Angular2的ngOnInit和ngAfterViewInit有什么区别?

时间:2016-11-26 10:27:18

标签: angular ngoninit

我无法理解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'));
  }
}

3 个答案:

答案 0 :(得分:43)

第一次调用ngOnInit()后调用

ngOnChanges()。每次通过变更检测更新输入时,都会调用ngOnChanges()

在最初呈现视图后调用

ngAfterViewInit()。这就是@ViewChild()取决于它的原因。在呈现视图成员之前,您无法访问它们。

答案 1 :(得分:15)

在第一次检查指令的数据绑定属性之后,以及在检查其任何子项之前,立即调用<{ngOnInit()。只有在实例化指令时才会调用它。

在组件的视图之后调用

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

答案 2 :(得分:0)

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

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

** ngAfterViewInit()在第一次检查子指令(或组件)的绑定时被调用。因此,它非常适合使用Angular 2组件访问和操作DOM。正如@GünterZö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',
            []
        )
    }
}