I have one smart component called ItemsComponent and two nested dumb components, ItemsListComponent and ItemComponent .
ItemsComponent html template contains ItemsListComponent .
// ItemsComponent <div> // ItemsListComponent <app-items-list [items]="items" (doDelete)="deleteItem($event)" > </app-items-list> <div>
and has a function called deleteItem :
deletItem(item) {
ItemsListComponent contains ItemComponent :
// ItemsListComponent <ul *ngFor="let item of items"> // ItemComponent <app-item [item]="item" (doDelete)="deleteItem($event)" > </app-item> </ul>
So, the html structure looks like this:
ItemsComponent (app-items) - ItemsListComponent (app-items-list) - ItemComponent (app-item)
ItemComponent has a button
<button (click)="deleteItem(item)">
and event emitter for deleteItem :
@Output() doDelete = new EventEmitter(); deleteItem(item) { this.doDelete.emit(item); }
When the delete button is pressed in the ItemComponent , the event only bubbles up to its immediate parent, ItemsListComponent , but does not make it ItemsComponent unless I add an identical event emitter function to the ItemsListComponent .
Smelly ItemsListComponent :
@Output() doDelete = new EventEmitter(); deleteItem(item) { this.doDelete.emit(item); }
It works this way, but ItemsListComponent now shares the smell of code using ItemsComponent , since they both have the same event emitter material, and the event must be passed from one component to another on it upward.
Is there a better way to do this?