web-dev-qa-db-fra.com

Angular Reliure de données à double sens et surveille pour les modifications du composant parent

Il semble qu'il n'ya aucun moyen de regarder les changements dans la composante parent lors de la liaison de données bidirectionnelle.

J'ai un composant d'entrée personnalisé pour la collecte d'une liste de balises. La liaison de données à double sens est la configuration et le fonctionnement entre ce composant et son parent.

// the parent component is just a form
// here is how I'm adding the child component
<input-tags formControlName="skillField" [(tags)]='skillTags' (ngModelChange)="skillTagUpdate($event)">
</input-tags>

Dans le composant parent, comment surveillez-vous la variable liée des modifications? Bien qu'il soit toujours à jour (je l'ai confirmé cela) Je ne peux pas trouver aucune indication sur la réaction à des changements.

J'ai essayé:

ngOnChanges(changes: SimpleChanges) {
    if (changes['skillTags']) {
        console.log(this.skillTags);  // nothing
    }
}

Et

skillTagUpdate(event){
    console.log(event); // nothing
}

Mise à jour : TWDB IMHO n'est pas ce qu'il est annoncé d'être. Chaque fois que j'arrive à cet endroit où Twdb semble être une solution i Rearchitect pour un service et une communication observable à la place.

10
TR3B

Votre implémentation n'est en réalité pas une base de données bidirectionnelle, le composant parent et enfant ne fait que partager une référence sur la même variable skillTags.

La syntaxe [(tags)]='skillTags' est sucre syntaxique pour [tags]='skillTags' (tagsChange)='skillTags = $event'

Vous devez implémenter tagsChange dans le composant enfant, comme celui-ci: @Output('tagsChange') tagsChange = new EventEmitter<any>();, alors à tout moment que vous souhaitez modifier tags dans le composant enfants, ne le faites pas directement, mais utilisez-le. this.tagsChange.emit(newValue) à la place.

À ce stade, vous aurez une réelle base de données bidirectionnelle et la composante parent est le propriétaire unique de la variable (responsable de l'application des modifications apportées aux enfants et de diffusion des enfants).

Maintenant, dans votre composant parent, si vous voulez faire plus que skillTags = $event (Fait implicitement [(tags)]='skillTags'), puis il suffit d'ajouter un autre écouteur avec (tagsChange)='someFunction($event)'.

Demo Stackblitz

1
Guerric P

1.Vous pouvez utiliser la sortie (EventMitter)

2. La solution la plus utilisée est RxJ/Subject. Il peut être observateur et observable en même temps

Usage:

1.Create Sujet Propriété en service:

import { Subject } from 'rxjs';

export class AuthService {
   loginAccures: Subject<boolean> = new Subject<boolean>();
}

2.Quand événement a eu lieu dans la page enfant/Utilisation de la composante:

logout(){
  this.authService.loginAccures.next(false);
}

3.Et abonnez-vous au sujet dans la page/composante parent:

constructor(private authService: AuthService) {
    this.authService.loginAccures.subscribe((isLoggedIn: boolean) => {this.isLoggedIn = isLoggedIn;})
}

Mise à jour

pour une liaison bidirectionnelle, vous pouvez utiliser ViewChild pour accéder aux éléments et aux propriétés de votre composant enfant.

<input-tags #test></<input-tags>

et dans le fichier TS

  @ViewChild('test') inputTagsComponent : InputTagsComponent;

save()
{
   var childModel = this.inputTagsComponent.Model;
}
0
moha noorani