62 votes

Sortie angulaire 2 du routeur-prise

Je veux faire la navigation à partir de composants enfants qui rendent à l'intérieur du routeur-prise. Mon composant parent possède une configuration de routeur et je souhaite naviguer manuellement sur certains événements. Mais je ne sais pas comment je peux transmettre d’enfant à parent des données (pour la navigation) sans sortie. Parce que cette construction ne fonctionne pas

  <router-outlet (navigateTo)="navigateToMessagePart($event)"></router-outlet>
 

Comment je peux le faire de la bonne manière? Peut-être naviguer depuis un enfant? Mais comment puis-je obtenir des méthodes parent de l'enfant. Un grand merci pour toute aide!

139voto

Antara Datta Points 981

<router-outlet></router-outlet> ne peut pas être utilisé pour émettre un événement de l'enfant du composant. Un moyen de communiquer entre les deux composants est d'utiliser un service commun.

Créer un service

de services partagés.ts

import { Observable } from 'rxjs/Observable';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class SharedService {
    // Observable string sources
    private emitChangeSource = new Subject<any>();
    // Observable string streams
    changeEmitted$ = this.emitChangeSource.asObservable();
    // Service message commands
    emitChange(change: any) {
        this.emitChangeSource.next(change);
    }
}

Maintenant injecter de l'instance du service ci-dessus dans le constructeur de la société mère et de l'enfant composant.

Le composant enfant sera en émettant un changement à chaque fois que le onClick() la méthode est appelée

enfant.composante.ts

import { Component} from '@angular/core';
@Component({
    templateUrl: 'child.html',
    styleUrls: ['child.scss']
})
export class ChildComponent {
    constructor(
        private _sharedService: SharedService
    ) { }

onClick(){
  this._sharedService.emitChange('Data from child');

 }
}

Le composant parent doit recevoir ce changement. Pour ce faire,la capture de l'abonnement à l'intérieur de la mère du constructeur.

parent.composante.ts

import { Component} from '@angular/core';
@Component({
    templateUrl: 'parent.html',
    styleUrls: ['parent.scss']
})
export class ParentComponent {
    constructor(
        private _sharedService: SharedService
    ) {
          _sharedService.changeEmitted$.subscribe(
        text => {
            console.log(text);
        });
      }

}

Espérons que cela aide :)

55voto

Günter Zöchbauer Points 21340

<router-outlet></router-outlet> est juste un espace réservé pour l'ajout de acheminés composants. Il n'y a pas de support pour tout type de liaison.

Vous pouvez créer une personnalisée <router-outlet> qui vous permet de le faire ou de plusieurs communes, l'utilisation d'un service partagé pour la communication entre le composant parent et acheminé composant.

Pour plus de détails, voir https://angular.io/docs/ts/latest/cookbook/component-communication.html

mise à jour

Il est maintenant un événement qui permet d'obtenir le composant ajouté

<router-outlet (activate)="componentAdded($event)" (deactivate)="componentRemoved($event)"></router-outlet>

qui permet de communiquer (appel getters, setters, et les méthodes) avec le composant en componentAdded()

Un service partagé est la meilleure façon de bien.

5voto

Bacem Points 76

La réponse donnée ci-dessus est correcte et complète. Je veux simplement ajouter à ceux pour qui la solution ne fonctionnait pas qu'ils devraient ajouter le service aux fournisseurs uniquement dans le composant parent et non à l'enfant pour garantir que vous obteniez un singleton du service, sinon deux instances de service seront établi. Cette réponse est inspirée du commentaire de @HeisenBerg dans la réponse précédente.

2voto

Raza Farooq Points 57

J'ai un peu changé par rapport à la réponse d'Antara Datta. J'ai créé un service d'abonné

 import {Injectable} from '@angular/core';
import {Subject} from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class Subscriber<T>
{
  protected observable = new Subject<T>();

  public next(item: T)
  {
    this.observable.next(item);
  }

  public subscribe(callback: (item:T)=>void) {
    this.observable.subscribe(callback);
  }
}
 

Chaque fois que j'ai besoin de deux composants pour partager des informations, j'injecte ce service dans le constructeur qui y est abonné:

  constructor(protected layoutOptions: Subscriber<Partial<LayoutOptions>>)
 {
    layoutOptions.subscribe(options => this.options = Object.assign({}, this.options, options));
 }
 

et celui qui le met à jour

 constructor(protected router: Router, protected apiService: ApiService, protected layoutOptions: Subscriber<Partial<LayoutOptions>>)
  {
    this.layoutOptions.next({showNavBar: false});
  }
 

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