Issue 1:
App Component template

<tabs>
<tab-link>Chat notification component goes here</tab-link>
<tab>Chat display component goes in here</tab>

<tab-link>Other Chat notification component goes here</tab-link>
<tab>Other Chat display component goes in here</tab>
</tabs>

Tabs Component template

<div (tabSwitch)="setActiveTab($event.target)" class="navigation">
<ng-content select="tab-link"></ng-content>
</div>
<ng-content select="tab"></ng-content>

UPDATE: This is the tab-link template(I forgot to put it in the first post)

<a (click)="select()" [class.active]="active">
<ng-content></ng-content>
</a>

Tab-Link Component ts

export class TabLink {
@Output('tabSwitch') tabSelected: EventEmitter<TabLink> = new EventEmitter();

select(){
this.tabSelected.emit(this);
console.log('click tab link');
}
}

Tabs Component ts

export class Tabs {
setActiveTab(link: TabLink):void{
console.log("hello", TabLink);
}
}

I would expect the setActiveTab method to fire when I click the TabLink, but nothing.

I have tried moving the tabSwitch event listener around, but nothing works.

Any thoughts?

Issue 2:
Previously discussed with @vsavkin and @jeffbcross

Background - programmatically listening to events propagated by children is difficult currently.

Consider:

You have a <accordion> component and n <accordion-item> components:

<accordion>
<accordion-item></accordion-item>
<accordion-item></accordion-item>
<accordion-item></accordion-item>
</accordion>

An accordion-item component might emit a select event/output, used to set it as the currently active item.

Currently the best way to achieve this is the accordion-item component would inject the parent accordion, and have the accordion-item register itself with the parent, and call a method to close the others

@Component({selector: 'accordion' })
class Accordion {
_items: []AccordionItem = [];
register(item: AccordionItem){
this._items.push(item);
}
toggleActive(selectedItem:AccordionItem){
this._items.forEach(item => {
if(item !== selectedItem){
item.active = false;
}
});
selectedItem.active = true;
}
}

@Component({selector: 'accordion-item' , inputs: ['active'] })
class AccordionItem {
active: boolean;
constructor(private accordion: Accordion){
accordion.register(this);
}
setActive(){
this.accordion.toggleActive(this);
}
}

Ideally, a child component would simply expose a 'select' event:

@Component({selector: 'accordion-item' })
class AccordionItem {
@Input() active: boolean;
@Output selected:EventEmitter<AccordionItem> = new EventEmitter();
active: boolean;
setActive(){
this.selected.emit(this);
}
}

The parent accordion can currently easily get ahold of the children via @ViewChildren() (or whatever) but there is a not a clean way to listen to events emitted from the children.

Proposed Syntax:

Implement a @ObserveChildren decorator (or similar) that would enable Observation of events emitted by child components:

@Component({selector: 'accordion' })
class Accordion {
//specify type and desired output to Observe.
@ObserveChildren(AccordionItem, 'select') childSelections: Observable<AccordionItem>
@ViewChildren(AccordionItem) children: Observable<AccordionItem>
afterViewInit(){
this.updates = Observable
.combineLatest(this.children, this.childSelections, (children, selected) => ({children, selected}))
.do(({children, selected) => children.map(child => { //update state }))
.subscribe();
}
onDestroy(){
this.updates.unsubscribe();
}
}

cc @pkozlowski-opensource @Foxandxss