无法捕获自定义事件

Unable to catch custom event

我设法发出自定义事件,但似乎无法在另一个组件中捕获该事件。

这是发射器:

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()');
    };
}

这是接收组件:

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');
    };
}

我的主机上有 toggled.emit(),但没有 event caught。知道我错过了什么吗?

请仔细查看变化。
注意此代码引用TypeScript

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

我放弃了发出和捕获事件的想法,因为侧边栏和汉堡包按钮(折叠或展开侧边栏)之间没有父子关系。

相反,我通过注入一个由公共父对象 (Window) 持有的服务实例将它们粘合在一起。

方法如下:

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({});
    }
}

此服务公开了一个组件可以订阅的可观察对象 sidebarToggled$。然后将 SidebarService 的一个新实例注入到 Window 组件中:

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) { }
}

然后将同一个实例注入到子组件中(不要将它们添加到 providers 数组中,否则您将获得一个与父组件中的实例断开连接的新实例!):

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

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');
        });
    }
}

因此,如果单击 HamburgerButton,将调用 SidebarService 上的 toggleSidebar。只有一个 ServiceSidebar 的实例(在 Window 中创建)被注入到子组件中,因此 Sidebar,它有 subscribed 到可观察的 sidebarToggled$相同服务的 将调用其功能,即 Sidebarcollapsed 属性 被切换。此 属性 现在可以与 Sidebarstyles 部分中的 ngClass 一起使用,折叠或展开它。