Angular 2自定义事件未被模板捕获

时间:2016-01-25 14:52:11

标签: javascript events typescript angular

我在Angular 2中遇到涉及自定义事件的问题。

点击特定的DOM元素后,我需要抛出一个cusotm事件。我能够发出事件,但看起来这个事件不会被应该监听的模板捕获。这是我的代码:

SidebarContent.ts

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



@Component({
    selector: 'ico-sidebar-content'
    , templateUrl: 'App/Pages/Filters/SidebarContent/SidebarContent.html'

})

export class SidebarContent {
    @Output('open') open = new EventEmitter();

    constructor() {
    }

    public emitEvent() {
        console.log("clicked!");
        this.open.emit(null);
        console.log("maybe emitted");
    }
}

当我点击emitEvent()中的以下元素时调用SidebarContent.html函数:

<li (click)="emitEvent()" *ngFor="#value of filter.values"><a><i
                                class="fa {{value.faIconClass}}"></i>{{value.name}}</a></li>

现在,应该捕获该事件的类位于 FilterTiles.ts

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

@Component({
    selector: 'ico-filter-tiles'
    , templateUrl: 'App/Pages/Filters/Components/FilterTiles/FilterTiles.html'
})


export class FilterTiles {
    public tiles = [{
            title: 'Sesso',
            faIconClass: 'fa-users',
            values: [
                'griffin'
                , 'simpson'
            ]
        }];

    public open(){
        console.log('Got it!'); 
    }
}

最后FilterTiles.html(我尝试将事件绑定到上面的open()函数的模板):

<h1 (open)="open()" (click)="open()">heeee</h1>
<div *ngFor="#tile of tiles" class="col-md-4">
    <div class="x_panel ico_filter_tiles">
        <div class="panel-heading">
            <h3 class="x_title">
                <i class="fa fa-map"></i><span class="panel-title-label">Azienda
                    di residenza</span> <a href="javascript:void(0);"><i
                    class="indicator glyphicon glyphicon-remove pull-right ico_remove"></i></a>
            </h3>
        </div>
        <div class="x_content">
            <div class="form-group">
                <div class="row">
                    <div class="col-xs-12">

                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-12">
                        <br>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-12">
                        <form class="form-horizontal">
                            <fieldset>
                                <ul class="ico_filter_ul_select form-control">
                                    <li *ngFor="#value of tile.values"><div class="checkbox">
                                            <label><input type="checkbox">ABCDE</label>
                                        </div></li>
                                </ul>
                            </fieldset>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

我无法找到我的错误,请有人帮助我吗?

谢谢;)

2 个答案:

答案 0 :(得分:4)

实际上,可以在应用SidebarContent组件的位置捕获事件。在您的情况下,名为ico-sidebar-content的元素:

<ico-sidebar-content (open)="doSomething()"></ico-sidebar-content>

您是在一个简单的h1元素上定义的,该元素与SidebarContent组件不对应。

修改

如果您想要与两个组件进行通信,则可以在共享服务中利用EventEmitter

@Injectable()
export class MyService {
  constructor() {
    this.myEvent = new EventEmitter();
  }
}

@Component({
})
export class SidebarContent {
  constructor(private service:MyService) {
  }

  emitEvent() {
    service.emit('data');
  }
}

@Component({
})
export class BodyContent {
  constructor(private service:MyService) {
  }

  listenEvent() {
    service.subscribe(
      data => {
        // do something with data
      }
    );
  }
}

小心定义服务提供者以使组件共享同一个实例(例如,在bootstrap函数内)。 希望它能帮到你, 亨利

答案 1 :(得分:0)

您可以做的是将事件发送到两个组件的父组件,然后绑定到另一个组件上的输入。我更喜欢蒂埃里的方式,但我还没有完全理解服务。实际上,他的答案让我对它们有了更好的了解。

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

@Component({
selector: 'ico-filter-tiles'
, templateUrl: 'App/Pages/Filters/Components/FilterTiles/FilterTiles.html'
})
inputs:['catchEvent'] // <--- Added this


export class FilterTiles implements OnChanges{ // <--- Added this
public tiles = [{
        title: 'Sesso',
        faIconClass: 'fa-users',
        values: [
            'griffin'
            , 'simpson'
        ]
    }];

public catchEvent; // <--- Added for easier code completion,not needed

ngOnChanges(e){ // <--- Added this, make sure to import OnChanges
    if(e['catchEvent']{
        this.open();
    }
}

public open(){
    console.log('Got it!'); 
}
}

现在将其添加到<ico-filter-tiles [catchEvent]="someVarToBind" ></ico-filter-tiles>。将someVarToBind添加到您的父组件,并将open()中的FilterTiles功能添加到父级组件中。

示例:

openFilterTiles(){
    this.someVarToBind = true;
}

然后添加<ico-sidebar-content (open)="openFilterTiles()"></ico-sidebar-content>

如果你这样做,你基本上使用你的父组件作为中介。您可能更容易理解这种方式,但我建议您尝试学习services做事方式。

我不喜欢传递它的原因是因为你最终在根组件或父组件中有一堆额外的函数/方法。