J'ai deux composants qui communiquent entre eux, un composant régulier (parent) et un composant modal bootstrap (enfant). Le parent et l'enfant ont tous deux une table avec des enregistrements. Dans la table des parents, chaque enregistrement a une case à cocher. Lorsque je coche une ou plusieurs cases et clique sur un bouton, un événement est déclenché qui tente de remplir la table de l'enfant.
La table de l'enfant est remplie et j'ai la possibilité de supprimer les enregistrements que je souhaite. Si je supprime certains enregistrements, ferme le modal (ferme l'enfant) et décide de renvoyer les mêmes données du parent à l'enfant, l'événement Input n'est pas déclenché. Cependant, si je choisis de vérifier différents enregistrements dans le parent et de les transmettre à l'enfant, l'événement Input est déclenché correctement.
Voici ce que j'ai:
ParentComponent.component.html
@Input('data')
set data(data: any) {
if (data !== undefined || data !== "") {
this.products = data;
console.log("data");
}
}
constructor() { }
ngOnInit() { }
ParentComponent .component.ts
private onNewProductRequest(toSend){
this.newProductRequest = toSend;
$('#createNewProductRequestModal').appendTo("body").modal('toggle');
}
ChildComponent.component.ts
<child-component #createNewProductRequestModal [data]="newProductRequest"></m-child-component>
Pour tester si les données sont modifiées avant de rendre la table de l'enfant, je consigne les données transmises par le parent à la console. Avec ce code, chaque fois que j'exécute la onNewProductRequest (toSend) du parent sans changer la variable toSend , le modal de l'enfant rend mais n'exécute pas le Input code> événement ne modifiant donc pas les données.
4 Réponses :
essayez
dans le composant enfant
import {Component, OnChanges, SimpleChanges, Input} from '@angular/core';
ngOnChanges(changes: SimpleChanges) {
for (let propName in changes) {
let change = changes[propName];
let curVal = JSON.stringify(change.currentValue);
let prevVal = JSON.stringify(change.previousValue);
console.log(curVal);
console.log(prevVal);
}
}
Je ne comprends pas ce que cela est censé faire mais rien ne change. Il a exactement le même comportement et ne s'exécute que si les données transmises sont différentes.
J'ai mis à jour quelques éléments et j'ai pu trouver une solution à l'aide de cela. Merci!
Si cela résout votre problème, vous pouvez cliquer dessus comme réponse utile.
Je l'ai fait, mais quelqu'un d'autre l'a rejeté, il apparaît donc comme 0
Vous pouvez utiliser ngOnChanges
Définition de angular docs
Une méthode de rappel qui est appelée immédiatement après que le détecteur de changement par défaut a vérifié les propriétés liées aux données si au moins une a changé, et avant que la vue et le contenu enfants ne soient vérifiés.
Vous avez une entrée sur l'élément enfant
ngOnChanges(changes: SimpleChanges) {
console.log(changes);
if ('nameOfInput' in changes) {
console.log('Old value: ', changes.nameOfInput.previousValue);
console.log('New value: ', changes.nameOfInput.currentValue);
}
}
Votre composant enfant doit implémenter OnChanges comme ceci:
XXX
Et à l'étape suivante, vous voulez faire quelque chose à chaque changement d'entrées.
export class ChildComponent implements OnChanges {
Regardez cet exemple.
Merci! Cela m'a définitivement conduit à une solution, mais je ne comprends toujours pas comment fonctionne ngOnChanges ...
Lorsque vous affectez les données à l'entrée, la première fois détectez les changements car l'objet change, mais ensuite si vous changez les propriétés à l'intérieur de l'objet, la référence et l'objet sont toujours les mêmes, donc les changements ne se déclenchent pas. La solution est de cloner l'objet que vous envoyez via l'entrée à l'enfant. Essayez de modifier cette ligne:
this.newProductRequest = {...toSend};
Pour cela:
this.newProductRequest = toSend;
Lorsque vous envoyez les mêmes données au composant enfant une deuxième fois, Angular n'enregistre pas cela comme une modification de @Input (), car vous passez la même référence d'objet que celle que vous avez passée la première fois, et Angular est juste en comparant les références.
Essayez ce petit changement:
private onNewProductRequest(toSend){
this.newProductRequest = { ...toSend };
$('#createNewProductRequestModal').appendTo("body").modal('toggle');
}
Cela signifie que vous passerez une copie superficielle de l'objet de données à l'enfant, plutôt qu'une simple version modifiée de l'objet d'origine . Comme cette copie superficielle aura une référence différente à l'Objet d'origine, Angular le prendra comme un changement et déclenchera votre setter @Input.