Reputation: 1609
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.
Upvotes: 8
Views: 5898
Reputation: 657416
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.
Upvotes: 8
Reputation: 202196
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 {
}
Upvotes: 4