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!
<router-outlet></router-outlet>
N'est qu'un espace réservé pour l'ajout de composants routés. Il n'y a pas de support pour tout type de liaison.
Vous pouvez créer un <router-outlet>
Personnalisé vous permettant de le faire ou plus commun, utilisez un service partagé pour communiquer entre le composant parent et le composant routé.
Pour plus de détails, voir https://angular.io/docs/ts/latest/cookbook/component-communication.html
mettre à jour
Il y a 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 (getters d’appel, setters et méthodes) avec le composant dans componentAdded()
Un service partagé est cependant le moyen préféré.
<router-outlet></router-outlet>
ne peut pas être utilisé pour émettre un événement à partir du composant enfant. Un moyen de communiquer entre deux composants consiste à utiliser un service commun.
Créer un service
service-partagé.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, injectez l'instance du service ci-dessus dans le constructeur des composants parent et enfant.
Le composant enfant émettra un changement chaque fois que la méthode onClick () sera appelée
child.component.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, capturez l'abonnement dans le constructeur du parent.
parent.component.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);
});
}
}
J'espère que cela t'aides :)
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 par le commentaire de @HeisenBerg dans la réponse précédente.
J'ai un peu changé avec 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});
}