2

I have a component which can be removed from the page when a close button is clicked. I have exposed a testClose event that a user can register to do some work when the component is closed. How do I register to that event to call a function when the component is closed? For example, I would like to increment the closeCounter by 1 when the TestComponent is closed. Here is the plnkr:

https://plnkr.co/edit/iGyzIkUQOTCGwaDqr8o0?p=preview

TestComponent which exposes an event:

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

@Component({
  selector: 'test',
  template: `
      <div class="box" *ngIf="!_close">
        <button class="close" (click)="close()">x</button>
      </div>
    `,
    styles:[
      `
        .box{
          background: yellow;
          height: 100px;
          width: 100px;
        }
      ` 
    ]
})
export class TestComponent{

  @Input("testClose") _close = false;
  @Output("testCloseChange") _closeChange = new EventEmitter<boolean>(false);

  close(): void{
    this._close = true;
    this._closeChange.emit(true);
  }

  open(): void{
    this._close = false;
    this._closeChange.emit(true);
  }

}

App Component which should register to the close event of the TestComponent to call some function.

import {Component} from 'angular2/core';
import {TestComponent} from './test.component';

@Component({
    selector: "my-app",
    template: `
      <div class="container">
        <test [testClose]="isClose"></test>
        Close Count: {{closeCount}}
      </div>
    `,
    directives: [TestComponent]
})
export class AppComponent{

  isClose: boolean = false;
  closeCount: number = 0;

  incrementClose(): void{
    this.closeCount++;
  }

}
takeradi
  • 3,661
  • 7
  • 29
  • 53

1 Answers1

6

Just add a listener to the event being emitted

(testCloseChange)="onTestCloseChange($event)"

So app component template will look like this

<div class="container">
   <test [testClose]="isClose" (testCloseChange)="onTestCloseChange($event)"></test>
   Close Count: {{closeCount}}
</div>

And inside the App component class you should define the onTestCloseChange

export class AppComponent{

  onTestCloseChange(event) {

  }

}
Daniel Pliscki
  • 1,913
  • 16
  • 24
  • Out of curiosity, since it's not the first time I see this being asked and since I've encountered the same problem before, anyone knows why I **need** to add the event listener to the template? Am I missing something obvious? – Aurelio Jul 13 '16 at 16:22
  • But how would you know when the child component emitted a certain event if the parent component is not listening to it? – Daniel Pliscki Jul 13 '16 at 16:35
  • It's up to the parent component to decide which events it wants to listen to. – Daniel Pliscki Jul 13 '16 at 16:36
  • Yes, true. And in your example I understand the reasoning. But then should I be able to use `@Input("testCloseChange")` inside the component and achieve the same thing? Isn't `@Input()` setting up a listener? Sorry for fussing you, but event sharing across component is still very unclear to me in Angular2 as you can see – Aurelio Jul 13 '16 at 17:11
  • Input() binds a data structure from a parent to a child component. It doesn't setup a listener. In other words, input() is parent sending data to children. Output() is children() notifying parent of something. – Daniel Pliscki Jul 13 '16 at 17:50
  • 2
    This is the first time when I see `&event`. Is it a typo for `$event`? – Estus Flask Jul 13 '16 at 18:00