2016-11-26 111 views
10

我不明白ngOnInitngAfterViewInit之間有什麼區別。ngOnInit和Angular2的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

「_you在呈現之前無法訪問視圖成員_」 - 那麼如何解釋'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', 
      [] 
     ) 
    } 
}