2016-11-26 14 views
10

ngOnInitngAfterViewInitの違いを理解できません。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')); 
    } 
} 

答えて

8

ngOnInit()ディレクティブのデータバインドプロパティが初めて確認されてきた直後に呼び出され、そしてその子のいずれかの前にチェックされています。ディレクティブがインスタンス化されると、一度だけ呼び出されます。

ngAfterViewInit()は、コンポーネントのビューと子ビューが作成された後に呼び出されます。コンポーネントのビューが完全に初期化された後に呼び出されるライフサイクルフックです。

16

ngOnInit()が呼び出された後に初めて呼び出されたngOnChanges()です。 ngOnChanges()は、変更検出によって入力が更新されるたびに呼び出されます。

ngAfterViewInit()ビューは最初にレンダリングされた後に呼び出されます。そのため、@ViewChild()がそれに依存しています。レンダリングされる前にビューメンバーにアクセスすることはできません。

+0

あなたが_rendered_を言うとき、あなたはそれが画面に表示されます意味ですか? (またはスクリーンに表示されるようにレンダリングされる) –

+2

DOMに追加されるとき。 'display:hidden'を設定するとレンダリングされますが、画面には表示されません。しかし、ブラウザdevtoolsを使ってDOMを調べると、マークアップを見ることができます。 –

+1

"ビューメンバーがレンダリングされる前にアクセスできませんでした。" - したがって、 'ViewChild'(vc)が' onNgInit'で利用可能であることをどのように説明しますか? https://plnkr.co/edit/AzhRe6bjnuPLKJWEJGwp?p=preview、説明していただけますか? –

0

内容は子供として渡される内容です。ビューは、現在のコンポーネントのテンプレートです。

コンテンツは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', 
      [] 
     ) 
    } 
} 
関連する問題