0

I have created two components named as Alert ticker and dropdown.
These two are separate component.
So lets come to the point.
I am using this alert ticker in some other page named as Dashboard.
so I am passing the callback function from dashboard page to ticker component and ticker component pass this callback function to dropdown component.

Dashboard.html

<ticker [data]="data"
  poll-time="10"
  [filter-data]="filterData"
  (on-polling)="onTickerPoll($event);"
  (on-scroll)="onTickerScroll($event);"
  (on-selection)="onTickerFilterChange($event);"></ticker>

Ticker.html

<dropdown  [list]="ctrl.filterData" (on-selection)="ctrl.onSelection($event)" ddl-class="form-control"></dropdown>

Ticker.ts

@Component({
    selector: 'od-ticker',
    directives: [DropdownComponent],
    templateUrl: '/app/components/ticker/ticker.html'
})

export class TickerComponent {
    @Input() data;
    @Output() onSelection: EventEmitter < string > = new EventEmitter();
}

But I am unable to do this . Please advice.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
Ashutosh Singh
  • 806
  • 1
  • 8
  • 20
  • What callback is "the callback" in "so I am passing the callback function"? `filterData`? What is `ctrl` in `ctrl.filterData`? – Günter Zöchbauer Feb 14 '16 at 15:32
  • ctrl is alias of the controller which has all these data. I want to call `onTickerFilterChange($event);` on change of dropdown. So ticker component should pass this callback function to dropdown . Please see dropdown.html – Ashutosh Singh Feb 14 '16 at 15:36
  • I would like to understand a bit more your question. Do you want to be notified in Dashboard that the Ticker Selected value has changed ? – Adrien BARRAL Feb 14 '16 at 16:40
  • @abarral: Yes, I want the same. – Ashutosh Singh Feb 15 '16 at 06:31

2 Answers2

0

Thanks guys for your help.

I have got the way to accomplish this.

@Output() onScroll: EventEmitter<string> = new EventEmitter();
@Output() onSelection: EventEmitter<string> = new EventEmitter();
onFilterChange(data){
  this.onSelection.next(data);
}

onScrollEnd(){
  this.onScroll.next({});
}

Ticker.html

<dropdown  [list]="ctrl.filterData" (on-selection)="ctrl.onFilterChange($event)" ddl-class="form-control"></dropdown>
Ashutosh Singh
  • 806
  • 1
  • 8
  • 20
0

There is a nice discussion on the Angular2 issue tracker about: "Why EventEmitter doesn't bubble up ?". This discussion is here.

So I think that you have to expose the event in the whole hierarchy of components...

I propose the following solution :

Dashboard.ts :

import {Component} from 'angular2/core';
import {MyTicker} from './my-ticker'

@Component({
  selector: 'dashboard-app',
  template: `<my-ticker [datas]="dashBoardDatas" (onSelection)="selectValueChanged($event)"></my-ticker>`,
  directives: [MyTicker],
})
export class DashboardApp {
  private dashBoardDatas: Array<string>;
  constructor(){
    this.dashBoardDatas = ["toto", "tata"];
  }
  selectValueChanged(value: string){
    console.log('Selected value changed to :' + value);
  }
}

And MyTicker.ts :

import {Component, Input, Output, EventEmitter, AfterViewInit} from 'angular2/core';
import {MySelect} from './my-select'

@Component({
  selector: 'my-ticker',
  template: `
  <p>
     <my-select [datas]="datas" (onSelection)="onSelection.emit($event)"></my-select>
  </p>
  `,
  directives: [MySelect]
})
export class MyTicker {
  @Input() datas: Array<string>;
  @Output() onSelection: EventEmitter < string > = new EventEmitter();
  constructor() {}
  ngAfterViewInit(){
    console.log("Datas in ticker : " + this.datas);
  }
}

And MySelect.ts :

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


@Component({
  selector: 'my-select',
  template: `
  <p>
  <select name="filter" (change)="onSelection.emit($event.target.value)">
    <option *ngFor="#item of datas" value="{{item}}">{{item}}</option>
  </select>
  </p>
  `
})
export class MySelect {
  @Input() datas: Array<string>;
  @Output() onSelection: EventEmitter < string > = new EventEmitter();
  constructor() {}
}

I did the following Plunkr to illustrate this.

As you can see, in the Dashboard, I have a method that I want to trigger when the content of the ticker's select change (selectValueChanged) (that is triggered when my-select selection change)... So we have to re-define the event emitter in "MyTicker".

The ticker and select contains the same members as in you question. An event emitter, and the filter's datas. When the select value change, I emit the event (thanks to (change)="onSelection.emit($event.target.value)" ). This event is "catched" by the ticker and re-emited, and then catched by dashboard (thanks to "(onSelection)="selectValueChanged($event)". So the method "selectValueChanged" of Dashboard is called when the event "OnSelection" of MySelect is fired.

Adrien BARRAL
  • 3,474
  • 1
  • 25
  • 37
  • You are on right track but you missed one thing. Your my-ticker has direct select element in your template rather it should be another component. By the way, I got the way to do this. which I have already posted. So Actually I am developing many isolated components which can be used anywhere. – Ashutosh Singh Feb 15 '16 at 08:19
  • Ok, so you want to notify the father of the father of select :) Isn't it ? – Adrien BARRAL Feb 15 '16 at 08:20
  • Yes if child component triggers event then grand father function should be executed – Ashutosh Singh Feb 15 '16 at 08:21