web-dev-qa-db-fra.com

Angular 2 événements interceptant des composants frères

Je viens juste de commencer à apprendre Angular 2, et ceci est ma toute première question sur Stack Overflow, alors allez-y ...

J'ai un composant externe avec deux composants internes imbriqués. J'ai un bouton dans InnerComponent1 qui, lorsque l'utilisateur clique dessus, déclenche un événement capturé par le composant externe, qui transmet ensuite la valeur (toujours true) à InnerComponent2. InnerComponent2 est affiché (* ngIf) en fonction de cette valeur.

Ça marche.

Buuuut .. InnerComponent2 a un bouton qui, lorsqu'il est cliqué, rend la valeur false, ce qui masque le composant.

Cela fonctionne aussi.

Mais une fois que j'ai caché InnerComponent2, le bouton dans InnerComponent1 qui affiche InnerComponent2 ne fonctionne plus. Je ne vois aucune erreur et j'ai confirmé que le composant externe est toujours en train de recevoir les événements.

Voici un plnkr qui montre le scénario: http://plnkr.co/edit/X5YnNVm0dpFwA4ddv4u7?p=preview

Des pensées?

Merci beaucoup.

Composant extérieur

//our root app component
import {Component} from 'angular2/core';
import {Inner1Component} from 'src/inner1';
import {Inner2Component} from 'src/inner2';

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <p>OuterComponent</p>
    <inner1 (show2)="show2Clicked = $event"></inner1>
    <inner2 [showMe]="show2Clicked"></inner2>
  `,
  directives: [Inner1Component, Inner2Component]
})
export class App {
  show2Clicked: boolean;
}

InnerComponent1

import {Component, EventEmitter, Output} from 'angular2/core'

@Component({
  selector: 'inner1',
  providers: [],
  template: `
    <p>inner1</p>
    <button (click)="showInner2()">Show inner2</button>
  `,
  directives: []
})
export class Inner1Component {
  @Output() show2 = new EventEmitter<boolean>();

  showInner2() {
    this.show2.emit(true);
  }
}

InnerComponent2

import {Component, Input} from 'angular2/core'

@Component({
  selector: 'inner2',
  providers: [],
  template: `
    <div *ngIf="showMe">
      <p>Inner2</p>
      <button (click)="showMe = false">Cancel</button>
    </div>
  `,
  directives: []
})
export class Inner2Component {
  @Input() showMe: boolean;
}
10
David

Les valeurs showMe et shwo2Clicked sont désynchronisées. 

J'ai ajouté et EventEmitter à <inner2> et changé

<inner2 [showMe]="show2Clicked"></inner2>

à

<inner2 [(showMe)]="show2Clicked"></inner2>

Je suppose que ça fonctionne maintenant comme prévu

http://plnkr.co/edit/tXzr3XgTrgMWMVzAw8d7?p=preview

update

La liaison [showMe] ne fonctionne que dans un sens. Lorsque show2Clicked est défini sur true, showMe sera également défini sur true. Cancel remet showMe à false. Si show2Clicked est à nouveau défini sur true, rien ne se produit car il est déjà true et showMe n'est pas mis à jour. Avec EventEmitter et la liaison abrégée à deux voies [(showMe)], show2Clicked est également défini sur false lorsque showMe est défini sur false et défini sur true est en réalité une modification transmise via la liaison. 

[(showMe)]="show2Clicked" est un raccourci pour [showMe]="show2Clicked" (showMeChange)="show2Clicked=$event" et le raccourci ne fonctionne que lorsque la sortie porte le même nom que l'entrée, mais avec une variable Change supplémentaire.

10
Günter Zöchbauer

J'ai eu le même problème, changer de formulaire en cliquant sur un bouton du composant frère. Ma solution était d'utiliser un service commun.

donc dans la composante 1:

<button (click)="showMessageForm()" >
showForm = true;
showMessageForm() {
    this.messageService.switchMessageForm(this.showForm);
    this.showForm = !this.showForm;
}

en service :

switchMessageFormEvent = new EventEmitter<boolean>();
switchMessageForm(bSwitch:boolean) {
    this.switchMessageFormEvent.emit(bSwitch);
}

dans la composante 2:

ngOnInit() {
    this.messageService.switchMessageFormEvent.subscribe(
        (bSwitch: boolean) => {
            if(bSwitch) {
                $('.message-input').slideDown("normal");
            }else {
                this.myForm.reset();
                $('.message-input').slideUp("normal");
            }
        }
    );
}
0
Adel Sanhaji