53 votes

Crochet angulaire 2 cycle de vie après que tous les enfants sont paraphés?

Je suis à la recherche d'un concept pour mettre en œuvre le cas suivant:

J'ai un parent composant de recherche qui a certains composants de la vue des enfants / contenu d'enfants pour l'affichage des facettes et des résultats de recherche. Je veux maintenant pour déclencher une recherche lorsque l'application a fini de se charger, de sorte que l'utilisateur ne voit pas une page vide.

Mon problème maintenant est que je ne trouve pas un cycle de vie de crochet qui correspond à mes besoins. Les facettes / les résultats de la recherche abonnez-vous pour les résultats de la recherche dans leur ngOnInit. J'ai donc besoin d'un crochet qui est appelée après que tous les composants enfants avaient terminé l'initialisation.

J'ai essayé les crochets sur le composant parent

  • ngAfterContentInit: ce qui est appelé avant ngOnInit est appelée sur les enfants
  • ngAfterViewInit: celui-ci fonctionne, mais après les résultats de la recherche de retour de la vue des enfants est mise à jour qui conduit à une erreur puisque l'action que manipuler la vue ne sont pas autorisés dans ngAfterViewInit

Une Idée de comment résoudre ce problème? Pour moi, il semble que je ne saisis pas quelque chose de fondamental ici.

Cheers

Tom

52voto

Tom Points 1331

J’ai fini par utiliser le crochet ngAfterViewInit() de la manière suivante:

Cela devrait être sûr à utiliser par rapport à d’autres invocations de setTimeout où un temps réel est fixé, car il doit commencer instantanément (et juste affecter le comportement de filetage / contexte)

7voto

Baconbeastnz Points 1712

Si vous avez besoin de votre composant parent pour attendre un comportement asynchrone personnalisé sur plusieurs composants pour enfants, alors voici une bonne solution que j’ai préparée.

N’importe quel composant enfant qui initialise asynchronement étendre ceci:

Exemple Composante enfant :

Maintenant, tout ce que votre composant Parent doit faire est le suivant:

4voto

Günter Zöchbauer Points 21340

Si vous avez également des enfants de contenu (transcluded en utilisant ) est alors le bon rappel cycle de ```` vie.

https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#aftercontent

1voto

Vale Steve Points 525

Faites en sorte que les composants de l’enfant émettent un événement sur son Init et l’écoutent là où vous en avez besoin

1voto

Inigo Points 2591

L'OP semble penser qu'il ne répond pas à ses besoins, ou n'est pas élégant, mais il semble que Vale de Steve réponse est l'approche la plus logique ici.

Dans mon cas, j'avais besoin d'attendre 2 enfant composants pour initialiser, qui contrôlent les panneaux gauche et droit de mon application. J'ai deux enfants composants de déclarer leur initialisation d'un service partagé:

  constructor(
      public _navigate: RouteNavigationService // service shared between all child components and parent
  ){}

  ngOnInit() {
    this._navigate.setChildInit(this.panel);
  }

De services partagés (RouteNavigationService):

  private _leftChildInit  = new Subject();
  private _rightChildInit = new Subject();

  leftChildInit$          = this._leftChildInit.asObservable();
  rightChildInit$         = this._rightChildInit.asObservable();

  setChildInit(panel){
    switch(panel){
      case 'leftPanel':
        console.log('left panel initialized!');
        this._leftChildInit.next(true);
        break;
      case 'rightPanel':
        console.log('right panel initialized!');
        this._rightChildInit.next(true);
        break;
    }
  }

Ensuite dans mon composant parent-je utiliser le zip de la méthode de combiner plusieurs Observables ensemble (Vous pouvez ajouter d'autres composants enfants ici) et attendre pour eux tout à la fin:

  childInitSub: Subscription;

  constructor(
      public _navigate: RouteNavigationService
  ) {
    this.childInitSub = Observable.zip( // WAIT FOR BOTH LEFT & RIGHT PANELS' ngOnInit() TO FIRE
        this._navigate.leftChildInit$,
        this._navigate.rightChildInit$).subscribe(data =>
        // Both child components have initialized... let's go!
    );
  }

Les OP membres dans un commentaire

"Je n'aime pas cela, car à chaque fois que j'ajoute un nouveau composant, j'ai besoin de attendre pour une période supplémentaire de onInit de l'événement et ont pour la mettre en œuvre"

Mais, en réalité, tout ce que vous avez à faire est de faire un autre Subject à votre service pour le nouveau composant enfant ngOnInit, et d'ajouter une ligne supplémentaire dans le composant parent zip méthode.

Notez que l'on a accepté de répondre ici, en utilisant ngAfterViewInit() n'est pas tout à fait la même chose que ci-dessus. Dans mon cas, à l'aide de ngAfterViewInit() a été la production d'un ExpressionChangedAfterItHasBeenCheckederror qui est au-delà de la portée de cette question, mais sert à démontrer que cette approche n'est pas en train de faire la même chose.

En revanche, la méthode ci-dessus est tout à fait littéralement déclenchée uniquement comme un résultat direct de tous vos composants enfants' ngOnInit() événements ayant déclenché.

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