8

Updated: Per Thierry Templier's response:

Below is essentially what I want to do, but unfortunately the inner components aren't rendering. Is there a way to nest components via their HTML selectors like so?

<custom-menu-bar-component (onCustomEvent)="handleEvent($event)">
    <custom-button-component></custom-button-component>
    <custom-dropdown-component></custom-dropdown-component>
</custom-menu-bar-component>

In my chrome debugger, I see only the outer component being rendered:

<custom-menu-bar-component>
    <div class="row">
        ** Nothing here, where my two inner components should be :(
    </div>
</custom-menu-bar-component>

And my components look like this:

CustomMenuBarComponent.ts:

import {Component} from 'angular2/core'
import {CustomButtonComponent} from './CustomButtonComponent'
import {CustomDropdownComponent} from './CustomDropdownComponent'

@Component({
    selector: 'custom-menu-bar-component',
    directives: [CustomButtonComponent, CustomDropdownComponent],
    template: `
        <div class="row"></div>
    `
})
export class CustomMenuBarComponent {
}

CustomButtonComponent.ts:

import {Component, EventEmitter} from 'angular2/core'
import {CustomEvent} from './CustomEvent'

@Component({
    selector: 'custom-button-component',
    outputs: ['onCustomEvent'],
    template: `
        <button type="button" class="btn btn-light-gray" (click)="onItemClick()">
        <i class="glyphicon icon-recent_activity dark-green"></i>Button</button>
    `
})
export class CustomButtonComponent {
    onCustomEvent: EventEmitter<CustomEvent> = new EventEmitter();
    onItemClick(): void {
        this.onCustomEvent.emit(new CustomEvent("Button Component Clicked"));
    }
}

CustomDropdownComponent is nearly identical to the CustomButtonComponent, but with different text. I'm just trying to get this very simple example working before I start making these components more useful and reusable.

Is this kind of approach possible? I'm trying to make it easy for others to take these components and create more of my custom menu bars with ease and simplicity.

6
  • What do you mean by "nest components via their HTML selectors? Commented Mar 30, 2016 at 15:34
  • After your update it looks like my answer is still valid. Commented Mar 30, 2016 at 16:48
  • Ahhhh, yes! Thank you Gunter, I didn't see your answer there. Commented Mar 30, 2016 at 16:50
  • I had deleted it after a while because I wasn't sure what you were actually looking for, but after your edit it became clear. Commented Mar 30, 2016 at 16:52
  • 1
    I guess moving (onCustomEvent)="handleEvent($event)" to the <custom-button-component></custom-button-component> element should do what you want. Events from EventEmitter don't bubble. Commented Mar 30, 2016 at 17:08

2 Answers 2

8

Not sure what your question is about but

<custom-menu-bar-component (onCustomEvent)="handleEvent($event)">
    <custom-button-component></custom-button-component>
    <custom-dropdown-component></custom-dropdown-component>
</custom-menu-bar-component>

requires <ng-content></ng-content> in the template of CustomMenuBarComponent

A bit of documentation can be found in https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html#!#aftercontent I had expected a bit more this was all I found.

http://blog.thoughtram.io/angular/2015/06/29/shadow-dom-strategies-in-angular2.html might contain some helpful information as well.

Update

Moving (onCustomEvent)="handleEvent($event)" to the <custom-button-component></custom-button-component> element should do what you want. Events from EventEmitter don't bubble.

Sign up to request clarification or add additional context in comments.

Comments

4

In fact you have the error because you don't instantiate your EventEmitter in the CustomButtonComponent component:

@Component({
  (...)
})
export class CustomButtonComponent {
  onCustomEvent: EventEmitter<CustomEvent> = new EventEmitter(); // <-----
  (...)
}

Otherwise your code seems correct.

Update

You need to use ng-content to include your sub components into the CustomMenuBarComponent one.

@Component({
  selector: 'custom-menu-bar-component',
  directives: [CustomButtonComponent, CustomDropdownComponent],
  template: `
    <div class="row">
      <ng-content></ng-content>
    </div>
  `
})
export class CustomMenuBarComponent {
}

3 Comments

Yes Exactly Eric ! I went down to that line, saw EventEmitter<CustomEvent> and skipped the line but didn't notice new EventEmitter part is not there. Eagle Eyes - Thierry...
Ohhhhh, yes, thank you! Instantiating my EventEmitter gets me past that console error. Unfortunately, the inner components aren't being rendered. I'll update my question accordingly.
I think that you need to leverage ng-content for this. I updated my answer accordingly...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.