86 votes

Quelle est la différence entre ngOnInit et ngAfterViewInit d'Angular2 ?

Je n'arrive pas à comprendre quelle est la différence entre ngOnInit et ngAfterViewInit .

J'ai trouvé que la seule différence entre eux est @ViewChild . Selon le code suivant, le elementRef.nativeElement en eux sont les mêmes.

Quelle scène devons-nous utiliser 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'));
  }
}

111voto

Günter Zöchbauer Points 21340

ngOnInit() est appelé après ngOnChanges() a été appelé la première fois. ngOnChanges() est appelé chaque fois que les entrées sont mises à jour par la détection des changements.

ngAfterViewInit() est appelé après le rendu initial de la vue. C'est pourquoi @ViewChild() en dépend. Vous ne pouvez pas accéder aux membres de la vue avant qu'ils ne soient rendus.

0 votes

Quand vous dites rendu Vous voulez dire qu'il apparaît sur l'écran ? ( ou envoyé pour être rendu pour apparaître sur l'écran)

2 votes

Quand il est ajouté au DOM. Si vous définissez display: hidden c'est rendu, mais pas visible à l'écran. Mais si vous examinez le DOM à l'aide des outils de développement du navigateur, vous serez en mesure de voir le balisage.

3 votes

" vous ne pouvez pas accéder aux membres de la vue avant qu'ils ne soient rendus " - Alors comment expliquez-vous que le ViewChild (vc) est disponible sur onNgInit ? plnkr.co/edit/AzhRe6bjnuPLKJWEJGwp?p=preview Pouvez-vous m'expliquer ?

32voto

Vishal Gulati Points 3279

ngOnInit() est appelé juste après que les propriétés liées aux données de la directive aient été vérifiées pour la première fois, et avant qu'aucun de ses enfants n'ait été vérifié. Il n'est invoqué qu'une seule fois lorsque la directive est instanciée.

ngAfterViewInit() est appelé après la création de la vue d'un composant et des vues de ses enfants. C'est un crochet de cycle de vie qui est appelé après que la vue d'un composant a été entièrement initialisée.

1voto

STEEL Points 649

Le contenu est ce qui est transmis aux enfants. View est le modèle du composant actuel.

La vue est initialisée avant le contenu et ngAfterViewInit() est donc appelé avant ngAfterContentInit() .

** ngAfterViewInit() est appelé lorsque les liaisons des directives (ou composants) enfants ont été vérifiées pour la première fois. Il est donc parfait pour accéder au DOM et le manipuler avec des composants Angular 2. Comme @Günter Zöchbauer l'a mentionné précédemment, c'est correct. @ViewChild() donc fonctionne bien à l'intérieur.

Exemple :

@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',
            []
        )
    }
}

0 votes

Je pense que vous vous trompez. ngAfterViewInit() s'exécute uniquement après ngAfterContentChecked() et ngAfterContentChecked() s'exécute uniquement après le ngAfterContentInit() et chaque ngDoCheck() suivant. Veuillez vous référer aux détails des hooks du cycle de vie d'Angular pour plus de détails. angular.io/guide/lifecycle-hooks

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X