title: Emitting output from ng-content to parent
body: <p>I'm attempting to create a wrapper for the Bootstrap split-style dropdown buttons using a button component and a dropdown component. I need to emit an output on <code>click</code> and on <code>document:click</code> from <code>ng-content</code> (which is a <code>&lt;button perf-btn&gt;</code>) to the parent <code>DropdownComponent</code>.</p>
  
  <p>There are several similar questions, but none seem to fit my use case.</p>
  
  <p>usage (app.component.html)</p>
  
  <pre><code>&lt;perf-drop [data]="items"&gt;
    &lt;button perf-btn&gt;Default Dropdown Button&lt;/button&gt; // click doesn't open dropdown
    &lt;button perf-btn dropdown="true"&gt;&lt;/button&gt;        // click opens dropdown
  &lt;/perf-drop&gt;
  </code></pre>
  
  <p>dropdown.component.html</p>
  
  <pre><code>&lt;ng-content select="[perf-btn]" (notify)='onNotify($event)')&gt;&lt;/ng-content&gt;
  &lt;ul class="dropdown-menu"&gt;
    &lt;template ngFor let-item [ngForOf]="data"&gt;
      &lt;li *ngIf="item.separator" role="separator" class="divider"&gt;&lt;/li&gt;
      &lt;li *ngIf="!item.separator" [class.disabled]="item.disabled"&gt;
        &lt;a [routerLink]="item.path" [ngClass]="getItemColor(item.color)"&gt;
          {{item.label}}
        &lt;/a&gt;
      &lt;/li&gt;
    &lt;/template&gt;
  &lt;/ul&gt;
  </code></pre>
  
  <p>dropdown.component.ts</p>
  
  <pre><code>import { Component, Input, ElementRef} from '@angular/core';
  
  @Component({
    selector: 'perf-drop',
    host: {
      '[attr.disabled]': 'disabled',
      '[class.open]': 'isOpen'
    },
    templateUrl: 'dropdown.component.html',
    styleUrls: ['dropdown.component.scss']
  })
  export class DropdownComponent {
    private _data: any[] = [];
    private _isOpen: boolean = false;
  
    @Input()
    get isOpen() { return this._isOpen; }
    set isOpen(value: boolean) { this._isOpen = value ? true : null; }
  
    @Input()
    get data(): any[] { return this._data; }
    set data(value: any[]) {
      this._data = value;
    }
  
    constructor(private _elementRef: ElementRef) { }
  
    private toggle(): void {
      this._isOpen = !this._isOpen;
    }
  
    private close(event): void {
      if (!this._elementRef.nativeElement.contains(event.target) &amp;&amp; this._isOpen)
        this._isOpen = false;
    }
  
    private getItemColor(color) {
      if (color) return `text--${color}`;
    }
  }
  </code></pre>
  
  <p>btn.component.ts</p>
  
  <pre><code>import { Component, ViewEncapsulation, Input, HostBinding, ChangeDetectionStrategy,
    ElementRef, Renderer, EventEmitter, Output } from '@angular/core';
  
  @Component({
    selector: 'button[perf-btn], input[perf-btn], a[perf-btn], div[perf-btn], perf-btn',
    host: {
      [snip conditional classes],
      "(click)": "_toggle()",
      "(document:click)": "_close($event)"
    },
    templateUrl: './btn.component.html',
    styleUrls: ['./btn.component.scss']
  })
  export class BtnComponent {
    [snip irrelevant fields]
    private _dropdown: boolean;
    private _state: boolean = false;
  
    @Input()
    get dropdown() { return this._dropdown; }
    set dropdown(value: boolean) { this._dropdown = value ? true : null; }
  
    get state() { return this._state; }
    set state(value: boolean) { this._state = value ? true : null; }
  
    [snip irrelevant getters/setters]
  
    @Output() notify: EventEmitter&lt;boolean&gt; = new EventEmitter&lt;boolean&gt;();
  
    constructor(private _elementRef: ElementRef, private _renderer: Renderer) { }
  
    _toggle() {
      console.log("notifying " + this._state);
      this._state = !this._state;
      this.notify.emit(this._state);
    }
  
    _close(event) {
      if (!this._elementRef.nativeElement.contains(event.target) &amp;&amp; this._state) {
        this._state = false;
        this.notify.emit(this._state);
      }
    }
  
    [snip irrelevant functions]
  }
  </code></pre>
  
  <p>btn.component.html</p>
  
  <pre><code>&lt;ng-content&gt;&lt;/ng-content&gt;
  &lt;span class="caret" *ngIf="dropdown"&gt;&lt;/span&gt;
  </code></pre>
  
  <p>dropdown.directive.ts</p>
  
  <pre><code>import { Directive } from '@angular/core';
  import { BtnDirective } from './btn.directive';
  
  @Directive({
    selector: `button[perf-drop], button[perf-drop], a[perf-drop], input[perf-drop],
              div[perf-drop], perf-drop`,
    host: {
      '[class.btn-group]': 'true',
      '[attr.disabled]': '[disabled]'
    }
  })
  export class DropdownDirective extends BtnDirective {}
  </code></pre>
  
  <p>btn.directive.ts</p>
  
  <pre><code>import { Directive } from '@angular/core';
  
  @Directive({
    selector: `button[perf-btn], button[perf-btn], a[perf-btn], input[perf-btn],
              div[perf-btn], perf-btn`,
    host: {
      '[class.btn]': 'true'
    }
  })
  export class BtnDirective {}
  </code></pre>