Hary
Hary

Reputation: 5818

Button Click getting called without being emitted in the child component

I am creating a custom component to simulate the split button. I've everything in place and seems working as expected. However, the app-button click event is called in the parent component without that being emitted in the child component. How that works?

In the below example and in the button component, nothing is emitted but the parent click event parentClick() getting called. How? Maybe, my assumption is wrong with EventEmitter. I understood in the way that only the child component emits the click then the parent pick it up?

@Output() clickEvent: EventEmitter<any> = new EventEmitter()

Split-Button.Component

import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'app-split-button',
  template: `<div class="btn-group dropdown" dropdown triggers="hover" #dp="bs-dropdown" (mouseleave)="dp.hide()">
              <button id="button-basic" dropdownToggle type="button" class="btn btn-success rounded-0 dropdown-toggle"
                      aria-controls="dropdown-basic">
                Save <span class="caret"></span>
              </button>
              <div class="dropdown-menu w-100 rounded-0 bg-success m-0 p-0" *dropdownMenu aria-labelledby="dropdownMenuButton" (mouseleave)="dp.hide()">
                <ng-content select="app-button"></ng-content>
              </div>
            </div>`
})
export class SplitButtonComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }
}

Button Component

import { Component, OnInit, Input} from '@angular/core';

@Component({
    selector: 'app-button',
    template: `<div>
                <button type="button">
                    {{buttonText}}
                </button>
            </div>`
})
export class ButtonComponent implements OnInit {

    @Input() buttonText: string; 

    ngOnInit() {

    }

//Here in the component, nothing is emitted but the parent click event parentClick() getting called. How?!
}

Parent-Component

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `<app-split-button>
              <app-button buttonText="Action1" (click)="parentClick()"></app-button>
            </app-split-button>`
})
export class AppComponent implements OnInit {
  title = 'Test Component';

   ngOnInit() {
  }

  parentClick() {
    console.log("parentClick");
  }
}

Upvotes: 0

Views: 292

Answers (2)

Barremian
Barremian

Reputation: 31105

The DOM structure of the AppComponent would be

<app-root>
  <app-split-button>
    <div class="btn-group dropdown" dropdown triggers="hover" #dp="bs-dropdown" (mouseleave)="dp.hide()">
      <button id="button-basic" dropdownToggle type="button" class="btn btn-success rounded-0 dropdown-toggle"
        aria-controls="dropdown-basic">
        Save <span class="caret"></span>
      </button>
      <div class="dropdown-menu w-100 rounded-0 bg-success m-0 p-0" *dropdownMenu aria-labelledby="dropdownMenuButton"
        (mouseleave)="dp.hide()">
        <app-button buttonText="Action1" (click)="parentClick()"></app-button>
      </div>
    </div>
  </app-split-button>
</app-root>

So naturally it will react to the standard click event from the DOM.

Upvotes: 1

Vimal Munjani
Vimal Munjani

Reputation: 290

Here, you are using the angular directive click in <app-button buttonText="Action1" (click)="parentClick()"></app-button> which listens to click event from the DOM, it has nothing to do with the parent-child relationship here, if the app-button is clicked, parentClick() method is called.

To learn how @Input / @Output works, please refer this https://ultimatecourses.com/blog/component-events-event-emitter-output-angular-2

Upvotes: 1

Related Questions