J'ai un composant parent qui va au serveur et récupère un objet:
// parent component
@Component({
selector : 'node-display',
template : `
<router-outlet [node]="node"></router-outlet>
`
})
export class NodeDisplayComponent implements OnInit {
node: Node;
ngOnInit(): void {
this.nodeService.getNode(path)
.subscribe(
node => {
this.node = node;
},
err => {
console.log(err);
}
);
}
Et dans l'un des nombreux présentoirs pour enfants:
export class ChildDisplay implements OnInit{
@Input()
node: Node;
ngOnInit(): void {
console.log(this.node);
}
}
Il ne semble pas que je puisse simplement injecter des données dans le fichier router-outlet
. Il semble que j'obtienne l'erreur dans la console Web:
Can't bind to 'node' since it isn't a known property of 'router-outlet'.
Cela a un peu de sens, mais comment pourrais-je faire ce qui suit:
- Récupérer les données "noeud" du serveur, depuis le composant parent?
- Passer les données que j'ai récupérées du serveur dans la sortie du routeur enfant?
Cela ne semble pas router-outlets
fonctionner de la même manière.
node
endroit où il est en tant que typestring
et cela ne semble pas fonctionner ou je fais quelque chose de malElementRef
événement à partir de la prise du routeur pour l'utiliser pour définir l'identifiant, mais je ne sais pas par cœur si ou comment le faire (uniquement sur mon téléphone)La réponse de Günters est excellente, je veux juste souligner une autre façon sans utiliser Observables.
Ici, nous devons cependant nous rappeler que ces objets sont passés par référence, donc si vous voulez faire un travail sur l'objet dans l'enfant et ne pas affecter l'objet parent, je suggérerais d'utiliser la solution de Günther. Mais si cela n'a pas d'importance, ou s'il s'agit en fait d' un comportement souhaité , je suggérerais ce qui suit.
Dans votre parent, vous pouvez attribuer la valeur:
Et dans vos enfants (ET parent), injectez le service partagé dans votre constructeur. N'oubliez pas de fournir le service au niveau du tableau des fournisseurs de niveau module si vous voulez un service singleton sur tous les composants de ce module. Sinon, ajoutez simplement le service dans le tableau des fournisseurs dans le parent uniquement , puis le parent et l'enfant partageront la même instance de service.
Et comme newman l'a gentiment souligné, vous pouvez également avoir
this.sharedService.sharedNode
dans le modèle html ou un getter:la source
Oui, vous pouvez définir les entrées des composants affichés via les prises de routeur . Malheureusement, vous devez le faire par programme, comme mentionné dans d'autres réponses. Il y a une grande mise en garde à cela lorsque des observables sont impliqués (décrit ci-dessous).
Voici comment:
(1) Connectez-vous à l'
activate
événement du routeur-sortie dans le modèle parent:(2) Basculez vers le fichier dactylographié du parent et définissez les entrées du composant enfant par programme à chaque fois qu'ils sont activés:
La version ci-dessus de
onOutletLoaded
est simplifiée pour plus de clarté, mais ne fonctionne que si vous pouvez garantir que tous les composants enfants ont exactement les mêmes entrées que vous affectez. Si vous avez des composants avec des entrées différentes, utilisez des protections de type:Pourquoi cette méthode peut-elle être préférée à la méthode de service?
Ni cette méthode ni la méthode de service ne sont «la bonne façon» de communiquer avec les composants enfants (les deux méthodes s'éloignent de la liaison de modèle pure), il vous suffit donc de décider de la manière la plus appropriée pour le projet.
Cependant, cette méthode vous permet d'éviter de créer l'objet intermédiaire (le service), qui couple étroitement le service et les composants enfants. Dans de nombreux cas, cela semble plus proche de la «voie angulaire» car vous pouvez continuer à transmettre des données à vos composants enfants via @Inputs. C'est également un bon choix pour les composants déjà existants ou tiers que vous ne voulez pas ou ne pouvez pas associer étroitement à ce service. D'un autre côté, cela peut ressembler moins à la manière angulaire lorsque ...
Caveat
La mise en garde avec cette méthode est que puisque vous passez des données par programme, vous n'avez plus la possibilité de transmettre des données observables dans votre modèle (surprise!). Cela signifie que vous perdez l'énorme avantage de la gestion angulaire du cycle de vie de l'observable pour vous lorsque vous utilisez le modèle pipe-async.
Au lieu de cela, vous devrez configurer quelque chose pour obtenir les valeurs observables actuelles chaque fois que la
onChildLoaded
fonction est appelée. Cela nécessitera probablement également un démontage de laonDestroy
fonction du composant parent . Ce n'est rien de trop inhabituel, il y a d'autres cas où cela doit être fait, comme lors de l'utilisation d'un observable qui n'atteint même pas le modèle.la source
Un service:
Composant:
la source
Il existe 3 façons de transmettre des données du parent aux enfants
Via le résolveur de routeur pour enfants si vous devez recevoir des données différentes
Via le résolveur de routeur parent si vous devez recevoir les mêmes données du parent
Remarque 1: Vous pouvez lire sur le résolveur ici . Il existe également un exemple de résolveur et comment enregistrer le résolveur dans le module, puis récupérer les données du résolveur dans le composant. L'enregistrement du résolveur est le même sur le parent et l'enfant.
Remarque 2: vous pouvez lire sur ActivatedRoute ici pour pouvoir obtenir des données du routeur
la source
Suite à cette question, dans Angular 7.2, vous pouvez transmettre des données de parent à enfant en utilisant l'état de l'historique. Donc tu peux faire quelque chose comme
Mais attention à être cohérent. Par exemple, supposons que vous souhaitiez afficher une liste sur une barre latérale gauche et les détails de l'élément sélectionné sur la droite en utilisant une sortie de routeur. Quelque chose comme:
Point 1 (x) | ..............................................
Point 2 (x) | ...... Détails de l'élément sélectionné .......
Point 3 (x) | ..............................................
Point 4 (x) | ..............................................
Maintenant, supposons que vous ayez déjà cliqué sur certains éléments. Cliquez sur les boutons de retour du navigateur pour afficher les détails de l'élément précédent. Mais que se passe-t-il si, entre-temps, vous avez cliqué sur le (x) et supprimez cet élément de votre liste? Ensuite, effectuez le clic arrière, vous montrera les détails d'un élément supprimé.
la source