2016-03-01 13 views
5

Attualmente sto insegnando a me stesso Angular2 e ho un problema pratico che sarebbe facile da correggere in AngularJS ma attualmente sto cercando tra gli esempi trovare una soluzione con Angular2. Ad ogni modo, ho un componente di livello superiore chiamato App e all'interno di quel componente ho una proprietà che applica una classe css, ecco il mio HTML che viene usato come modello di componente - puoi vedere dove desidero applicare la classe css usando ngClass. Il valore showMenu è solo un valore booleano.

<div class="navigation" role="navigation"> 
    <ul> 
     <li><a [routerLink]="['Home]">Home</a></li> 
     <li><a [routerLink]="['Mail']">Mail</a></li> 
     <li><a [routerLink]="['Friends']">Friends</a></li> 
     <li><a [routerLink]="['Games']">Games</a></li> 
    </ul> 
</div> 
<!-- below is where I wish to toggle the class --> 
<div class="site-wrap" [ngClass]="{'slide-right': showMenu}"> 
    <div class="container-fluid"> 
     <div class="row nav"> 
      <top-navigation></top-navigation> 
     </div> 
    </div> 

    <div class="container-fluid content-gradient"> 
     <div class="row"> 
      <div class="col-md-10"> 
       <router-outlet></router-outlet> 
      </div> 
      <div class="col-md-2"> 
       <contacts-list></contacts-list> 
      </div> 
     </div> 
    </div> 

    <div class="container-fluid footer"> 
     <footer-navigation></footer-navigation> 
    </div> 
</div> 

Ecco il codice Componente per App (non tanto da vedere qui ...)

export class App { 

    showMenu: boolean = false; 
    constructor() { 
    } 
    // I need to listen for the toggle somehow? 
    toggleMenu():void { 
     this.showMenu = !this.showMenu; 
    } 

} 

ora si può vedere ho un componente figlio con il selettore top-navigation. Questo componente TopNavigation ha un metodo su un pulsante che desidero commutare il valore di showMenu nel componente principale/principale. Ecco il mio codice finora (solo piccoli estratti)

export class TopNavigation { 

      constructor() { 
      // Things happening here 
      } 

      toggleMenu():void { 
      // I want to toggle the parent property by somekind of $emit 
      } 
    } 

qui è il modello HTML (non tutti) per la componente.

<div class="col-xs-2 col-sm-1 hidden-md hidden-lg hamburger-menu"> 
    <button class="btn btn-default" (click)="toggleMenu()">&#9776;</button> 
</div> 

In AngularJS avrei un $scope.$emit sulla funzione toggleMenu e nel genitore avrei una $scope.$on di ascoltare per l'evento. Attualmente sto leggendo su EventEmitters in Angular2, ma se qualcuno ha una spiegazione/esempio rapido sarei molto riconoscente soprattutto perché penso che questo sia un compito quotidiano/pratico per gli sviluppatori angolari.

+0

Se si dispone di un rapporto diretto tra genitori e figli, io preferisco la risposta di Günter. Se hai bisogno di cambiare il valore da più componenti, allora vai con la risposta di Theyry (ma usa un Observable piuttosto che un EventEmitter). –

risposta

5

Potrei sfruttare un servizio condiviso che definisce una proprietà EventEmitter. Il componente App si iscriverà su di esso per ricevere una notifica quando l'evento corrispondente viene attivato dal componente TopNavigation.

  • servizio Shared

    @Injectable() 
    export class MenuService { 
        showMenuEvent: EventEmitter = new EventEmitter(); 
    } 
    

    Non dimenticare di definire il corrispondente provider nella funzione di bootstrap per essere in grado di condividere la stessa istanza del servizio per l'intera applicazione: `bootstrap (App, [MenuService]);

  • App componente

    @Component({ ... }) 
    export class App { 
        showMenu: boolean = false; 
        constructor(menuService: MenuService) { 
        menuService.showMenuEvent.subscribe(
         (showMenu) => { 
         this.showMenu = !this.showMenu; 
         } 
        ); 
    } 
    

    }

  • TopNavigation componente:

    export class TopNavigation { 
        constructor(private menuService: MenuService) { 
        // Things happening here 
        } 
    
        toggleMenu():void { 
        this.showMenu = this.showMenu; 
        this.menuService.showMenuEvent.emit(this.showMenu); 
        } 
    } 
    

Vedere questa domanda per maggiori dettagli:

+1

È grandioso e sto solo leggendo il collegamento, tuttavia nell'emissione nel componente TopNavigation presumo che non sia necessario inviare alcun dato da .emit(), poiché non mantengo lo showMenu in quel componente. Comunque vedo come potrei passare le informazioni dovrei volere. Anche nel mio MenuService ottengo l'errore 'Tipo generico 'EventEmitter ' richiede 1 tipo argomento (s)' Presumo che ci manca qualcosa lì. Ma la tua risposta era proprio ciò di cui avevo bisogno - ora capisco! –

4

È possibile utilizzare legame a due vie.

<top-navigation [(toggleMenu)]="showMenu"></top-navigation> 

forse a senso unico farebbe pure, non so le vostre esigenze

<top-navigation (toggleMenuChange)="showMenu=$event"></top-navigation> 
export class TopNavigation { 
     @Output() toggleMenuChange: EventEmitter = new EventEmitter(); 

     // for two-way binding 
     @Input() toggleMenu:boolean = false; 

     constructor() { 
     // Things happening here 
     } 

     toggleMenu():void { 
     this.toggleMenu = !this.toggleMenu; 
     this.toggleMenu.emit(this.toggleMenu); 
     } 
}