2016-02-28 12 views
10

ho appena iniziato l'apprendimento angolare 2, e questa è la mia prima domanda Stack Overflow, quindi ecco qui ...angolare 2 evento di cattura tra i componenti di pari livello

Ho un componente esterno con due componenti interni nidificati. Ho un pulsante in InnerComponent1 che, quando si fa clic, attiva un evento catturato dal componente esterno, che quindi trasmette il valore (sempre true) a InnerComponent2. InnerComponent2 viene visualizzato (* ngIf) in base a tale valore.

Funziona.

Buuuut .. InnerComponent2 ha un pulsante che, quando viene premuto, rende falso quel valore, che nasconde il componente.

Anche questo funziona.

Ma una volta che ho nascosto InnerComponent2, il pulsante InnerComponent1 che visualizza InnerComponent2 non funziona più. Non vedo errori e ho confermato che il componente esterno sta ancora ricevendo gli eventi.

Ecco un plnkr che mostra lo scenario: http://plnkr.co/edit/X5YnNVm0dpFwA4ddv4u7?p=preview

Qualche idea?

Grazie mille.

componente esterno

//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; 
} 

risposta

9

L'012.e shwo2Clicked valori fuori sincrono.

ho aggiunto e EventEmitter a <inner2> e cambiato

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

a

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

Credo che sia ora lavora come ci si aspetta

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

aggiornamento

La rilegatura [showMe] funziona solo in una direzione. Quando show2Clicked è impostato su true, showMe verrà impostato su true. Annulla set showMe torna a falso. Se quindi show2Clicked è impostato nuovamente su true, non accade nulla perché è già true e showMe non è aggiornato.Con lo EventEmitter e la combinazione stenografica a due vie [(showMe)], show2Clicked è impostato anche su false quando showMe è impostato su false e impostandolo su true è in realtà una modifica propagata verso il basso tramite l'associazione.

[(showMe)]="show2Clicked" è un'abbreviazione per [showMe]="show2Clicked" (showMeChange)="show2Clicked=$event" e l'abbreviazione funziona solo quando l'uscita ha lo stesso nome come ingresso, ma con un ulteriore Change

+0

perfetto. Grazie mille per la tua pronta risposta. Funziona come previsto. Giusto per chiarire esattamente cosa sta succedendo qui: abbiamo bisogno dell'emettitore di eventi in 'inner2' solo per attivare la rivalutazione delle variabili e del rerender? Perché l'evento 'showMeChange' che viene emesso non viene catturato da nessuna parte. – David

+0

Ho aggiornato la mia risposta (era troppo lungo per un commento). –

+0

Stenografia. Gotcha. Questo è esattamente quello che stavo cercando. ** Grazie mille. ** La documentazione ufficiale di Angular2 è ancora carente, comprensibilmente. – David

0

Ho avuto lo stesso problema, commutazione di una forma su clic su un pulsante da componente sibling . La mia soluzione era usare un servizio comune.

così nel componente 1:

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

in servizio:

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

nel componente 2:

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