web-dev-qa-db-fra.com

Angular 2 - Comment déclencher une méthode sur un enfant du parent

Il est possible d’envoyer des données du parent à un enfant via @Input, ou d’appeler une méthode du parent à partir de l’enfant avec @Output, mais j’aimerais faire exactement le contraire, c’est-à-dire appeler une méthode le enfant du parent. Fondamentalement, quelque chose comme ça:

@Component({
  selector: 'parent',
  directives: [Child],
  template: `
<child
  [fn]="parentFn"
></child>
`
})
class Parent {
  constructor() {
    this.parentFn()
  }
  parentFn() {
    console.log('Parent triggering')
  }
}

et l'enfant:

@Component({
  selector: 'child',
  template: `...`
})
class Child {
  @Input()
  fn() {
    console.log('triggered from the parent')
  }

  constructor() {}
}

Background est une sorte de requête "get", c'est-à-dire d'obtenir un statut à jour de la part de l'enfant.

Maintenant, je sais que je pourrais y parvenir avec un service et un sujet/observable, mais je me demandais s’il n’y avait pas quelque chose de plus simple?

47
Christophe Vidal

Je pense que ceux-ci pourraient être ce que vous cherchez:

https://angular.io/guide/component-interaction#parent-interacts-with-child-via-local-variable

https://angular.io/guide/component-interaction#parent-calls-an-viewchild

Vous pouvez accéder aux propriétés et méthodes enfants à l'aide de variables locales dans le modèle ou à l'aide de la commande @ViewChild décorateur dans la classe de composant du parent.

53
awiseman

@ViewChild est la bonne solution, mais la documentation liée ci-dessus était un peu obscure pour moi, alors je donne une explication un peu plus conviviale qui m'a aidé à la comprendre.

Ayons un ChildComponent avec une méthode:

whoAmI() {
  return 'I am a child!!';
}

Et le composant parent, où nous pouvons appeler la méthode ci-dessus en utilisant la technique '@ ViewChild`:

import { Component, ViewChild, OnInit } from '@angular/core';

import { ChildComponent } from './child.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {

  @ViewChild(ChildComponent) child: ChildComponent;

  ngOnInit() {
    console.log(this.child.whoAmI()); // I am a child!
  }
}
22
mpro