2016-03-26 24 views
2

Es ist mir gelungen, ein benutzerdefiniertes Ereignis auszugeben, aber dieses Ereignis kann nicht in einer anderen Komponente abgefangen werden.Ich konnte kein benutzerdefiniertes Ereignis abfangen

Hier ist der Emitter:

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

@Component({ 
    selector: 'x-hamburger-button', 
    template: ` 
     <div (click)="toggleSidebar()"> 
      <i class="fa fa-bars"> 
       <a href="#"></a> 
      </i> 
     </div> 
     ` 
}) 

export class HamburgerButton { 
    @Output() toggled = new EventEmitter(); 
    toggleSidebar = function() { 
     this.toggled.emit(); 
     console.log('toggled.emit()'); 
    }; 
} 

und dies ist die Empfangs-Komponente:

import { Component } from 'angular2/core'; 
import { HamburgerButton } from './hamburger-button.component'; 

@Component({ 
    selector: "x-sidebar", 
    template: ` 
     <div (toggled)="onToggled()" [ngClass]="{collapsed: collapsed}"> 
     </div> 
     ` 
}) 

export class Sidebar { 
    collapsed: boolean = false; 
    onToggled = function() { 
     this.collapsed = !this.collapsed; 
     console.log('event caught'); 
    }; 
} 

ich toggled.emit() auf meiner Konsole zu bekommen, aber es gibt keine event caught. Irgendeine Idee, was ich vermisse?

Antwort

1

ich die Idee zu emittieren und fangen ein Ereignis verlassen, um Typoskript, weil es keine Kind-Beziehung zwischen der Seitenleiste Eltern und der Hamburger Schaltfläche (die die Seitenleiste zusammenfaltet oder erweitert).

Stattdessen habe ich diese zusammengeklebt, indem ich eine Dienstinstanz injiziert habe, die von einem gemeinsamen übergeordneten Objekt (Window) gehalten wird.

Hier ist, wie:

import { Injectable } from 'angular2/core'; 
import { Subject } from 'rxjs/Subject'; 

@Injectable() 
export class SidebarService { 
    private sidebarToggledSource = new Subject(); 
    sidebarToggled$ = this.sidebarToggledSource.asObservable(); 

    toggleSidebar(collapsed: boolean) { 
     this.sidebarToggledSource.next({}); 
    } 
} 

Dieser Service stellt eine beobachtbare sidebarToggled$, die Komponenten abonnieren. Eine neue Instanz von SidebarService wird dann in die Window Komponente injiziert:

import { Component } from 'angular2/core'; 
import { NavigationBar } from './navigation-bar.component'; 
import { Sidebar } from './sidebar.component'; 
import { SidebarService } from './sidebar.service'; 

@Component({ 
    selector: 'x-window', 
    directives: [NavigationBar, Sidebar], 
    template: ` 
      <x-navigation-bar></x-navigation-bar> 
      <div> 
       <x-sidebar></x-sidebar> 
       <div class="content"></div> 
      </div> 
     `, 
    providers: [SidebarService] 
}) 

export class Window { 
    constructor (private sidebarService: SidebarService) { } 
} 

Die gleiche Instanz dann in die untergeordneten Komponenten injiziert wird (nicht hinzufügen, sie an die providers Array oder sonst werden Sie eine neue Instanz erhalten, die getrennt von dem in der übergeordneten Komponente): So

import { Component } from 'angular2/core'; 
import { SidebarService } from './sidebar.service'; 

@Component({ 
    selector: 'x-hamburger-button', 
    template: ` 
     <div (click)="toggleSidebar()"> 
      <i class="fa fa-bars"> 
       <a href="#"></a> 
      </i> 
     </div> 
     ` 
}) 

export class HamburgerButton { 
    constructor (private sidebarService: SidebarService) { } 
    toggleSidebar() { 
     this.sidebarService.toggleSidebar(true); 
    }; 
} 

und

import { Component } from 'angular2/core'; 
import { SidebarService } from './sidebar.service'; 

@Component({ 
    selector: "x-sidebar", 
    template: ` 
     <div [ngClass]="{collapsed: collapsed}"> 
      <ul> 
       <li>Menu Item 1</li> 
       <li>Menu Item 2</li> 
       <li>Menu Item 3</li> 
       <li>Menu Item 4</li> 
       <li>Menu Item 5</li> 
      </ul> 
     </div> 
     `, 
    styles: [ 
     ... 
    ] 
}) 

export class Sidebar { 
    collapsed: boolean = false; 
    constructor (private sidebarService: SidebarService) { 
     sidebarService.sidebarToggled$.subscribe(data => { 
      this.collapsed = !this.collapsed; 
      console.log('event caught'); 
     }); 
    } 
} 

, wenn HamburgerButton wird geklickt, toggleSidebar auf SidebarService wird aufgerufen. Es gibt nur eine Instanz von ServiceSidebar (erstellt in Window), die in die untergeordneten Komponenten injiziert wird, so Sidebar, die subscribe d auf die beobachtbaren sidebarToggled$ desselben Dienst seine Funktion aufgerufen wird haben muss, das heißt die collapsed Eigenschaft Sidebar wird umgeschaltet. Diese Eigenschaft kann jetzt mit ngClass im Bereich styles von Sidebar verwendet werden, um sie zusammenzufalten oder zu erweitern.

1

Bitte beachten Sie die Änderungen sorgfältig.
Hinweis: dieser Code bezieht sich

export class HamburgerButton { 
    @Output() toggled = new EventEmitter(); 
    toggleSidebar() {     //changed 
     this.toggled.emit('Angular2'); //value emitted 

    }; 
} 

@Component({ 
     selector: "x-sidebar", 
     template: ` 
      <x-hamburger-button (toggled)="onToggled($event)" [ngClass]="{collapsed: collapsed}">    //changed 
      </x-hamburger-button>  //changed 
      ` 
    }) 


export class Sidebar { 
    collapsed: boolean = false; 
    onToggled(value) {    //changed 
     this.collapsed = !this.collapsed; 
     console.log(value);   //Angular2 <-------- 
    }; 
} 
+0

Ok, ich kann also nur benutzerdefinierte Ereignisse von untergeordneten Komponenten abfangen (siehe oben, der Hamburger-Button ist jetzt in der Sidebar)? –

+0

Haben Sie meinen Code überprüft? Was ist die Beziehung zwischen Hamburger und Sidebar? Gibt es irgendwelche? Sie importieren hamburgerbutton in der Seitenleiste, aber warum? Um dies alles zu beantworten, schauen Sie sich meinen Code genau an. – micronyks

+0

Ja, ich habe deine Lösung versucht, aber es hat nicht funktioniert, zumindest nicht für mich. Ich habe Hamburger-Button importiert, weil ich in einem anderen Post gelesen habe, dass das nötig war (um das Event bekannt zu machen? Keine Ahnung).Was mich in meinen Tracks stoppte war, dass du einen weiteren Hamburger-Button in die Sidebar steckst (wo ich aus offensichtlichen Gründen nicht sein will - die Sidebar zusammenklappt und der Button weg ist). Wie dem auch sei, ich werde versuchen, das auf eine andere Art und Weise zu arrangieren, mit einem Service, der zwischen Sidebar und Hamburger-Button vermittelt. –

Verwandte Themen