J'ai un composant parent qui est l'obtention de données à partir d'un serveur par l'intermédiaire d'un service. J'ai besoin de certaines de ces données à passer au composant Enfant.
J'ai essayé de transmettre ces données avec l'habituel @Input()
cependant comme je m'y attendais les données que je reçois dans le composant Enfant est - undefined
.
Exemple
Composant Parent
@Component({
selector: 'test-parent',
template: `
<test-child [childData]="data"></test-child>
`
})
export class ParentComponent implements OnInit {
data: any;
ngOnInit() {
this.getData();
}
getData() {
// calling service and getting data
this.testService.getData()
.subscribe(res => {
this.data = res;
});
}
}
Composant Enfant
@Component({
selector: 'test-child',
template: `
<!-- Content for child.... -->
`
})
export class ChildComponent implements OnInit {
@Input() childData: any;
ngOnInit() {
console.log(childData); // logs undefined
}
}
J'ai gardé l'exemple simple pour montrer ce que je suis en train de faire. Ma question est de savoir si il est possible de transmettre des données à l'enfant après l'initialisation. Je ne suis pas sûr, mais serait les deux sens de la liaison de données de l'aide dans ce cas?
Plus D'Enquête
Après la publication des réponses que j'ai essayé d'utiliser l' ngOnChanges
cycle de vie du crochet. La question que je vais avoir, c'est que l' ngOnChanges
fonction n'est pas déclenché lorsque les données sont mises à jour. Les données est un objet qui est pourquoi je pense que les changements ne sont pas détectés.
Code mis à jour dans le Composant Enfant
@Component({
selector: 'test-child',
template: `
<!-- Content for child.... -->
`
})
export class ChildComponent implements OnChanges {
@Input() childData: any;
ngOnChanges() {
console.log(childData); // logs undefined
}
}
J'ai essayé de faire un test avec le Live Exemples sur Plunker de l'Angulaire de l'équipe présentant le Cycle de vie des Crochets. Dans le test que j'ai mis à jour le OnChangesComponent à passer un objet qui, comme on peut le voir dans l'exemple lors de la mise à jour d'un objet de la ngOnChanges ne détecte pas le changement. (Ceci est également indiqué dans cette question)
https://plnkr.co/edit/KkqwpsYKXmRAx5DK4cnV
Semble que le ngDoCheck
pourraient aider à résoudre ce problème, mais il me semble qu'il ne serait pas aider à la performance à long terme, car chaque changement est détecté par le présent Cycle de vie du Crochet.
Je sais aussi que je pourrais probablement utiliser l' @ViewChild()
pour accéder au Composant Enfant et de définir les variables dont j'ai besoin, mais je ne pense pas que pour ce cas d'utilisation, il fait beaucoup de sens.
La publication de plus de code pour aider à expliquer mieux
Composant Parent
@Component({
selector: 'test-parent',
template: `
<test-child [childType]="numbers" [childData]="data" (pickItem)="pickNumber($event)">
<template let-number>
<span class="number" [class.is-picked]="number.isPicked">
{{ number.number }}
</span>
</template>
</test-child>
<test-child [childType]="letters" [childData]="data" (pickItem)="pickLetter($event)">
<template let-letter>
<span class="letter" [class.is-picked]="letter.isPicked">
{{ letter.displayName }}
</span>
</template>
</test-child>
<button (click)="submitSelections()">Submit Selection</button>
`
})
export class ParentComponent implements OnInit {
data: any;
numbersData: any;
lettersData: any;
ngOnInit() {
this.getData();
}
getData() {
// calling service and getting data for the game selections
this.testService.getData()
.subscribe(res => {
this.data = res;
setChildData(this.data);
});
}
setChildData(data: any) {
for(let i = 0; i < data.sections.length; i++) {
if(data.sections[i].type === 'numbers') {
this.numbersData = data.sections[i];
}
if(data.sections[i].type === 'letters') {
this.lettersData = data.sections[i];
}
}
}
pickNumber(pickedNumbers: any[]) {
this.pickedNumbers = pickedNumbers;
}
pickLetter(pickedLetters: any[]) {
this.pickedLetters = pickedLetters;
}
submitSelections() {
// call service to submit selections
}
}
Composant Enfant
@Component({
selector: 'test-child',
template: `
<!--
Content for child...
Showing list of items for selection, on click item is selected
-->
`
})
export class ChildComponent implements OnInit {
@Input() childData: any;
@Output() onSelection = new EventEmitter<Selection>;
pickedItems: any[];
// used for click event
pickItem(item: any) {
this.pickedItems.push(item.number);
this.onSelection.emit(this.pickedItems);
}
}
C'est plus ou moins le code que j'ai. Fondamentalement, j'ai un parent qui gère les sélections à partir de composants enfants, puis-je soumettre ces sélections pour le service. J'ai besoin de transmettre certaines données à l'enfant parce que j'essaie d'avoir l'objet que l'enfant retourne dans le format que le service attendu. Cela m'aiderait à ne pas créer de l'ensemble de l'objet prévu par le service du composant parent. Aussi, il serait de rendre l'enfant réutilisables, dans le sens qu'il renvoie ce que le service attend.
Mise à jour
J'apprécie le fait que les utilisateurs sont toujours l'affichage des réponses sur cette question. Notez que le code qui a été écrit ci-dessus a fonctionné pour moi. Le problème que j'ai eu était que dans un modèle particulier, j'ai eu une faute de frappe qui a causé pour que les données soient undefined
.
Espérons qu'il s'avère être utile :)