Mario G.
Mario G.

Reputation: 671

How to bubble up angular2 custom event

Parent template:

<ul>
   <tree-item [model]="tree" (addChild)="addChild($event)"></tree-item>
</ul>

Tree item template:

<li>
  <div>{{model.name}}
    <span [hidden]="!isFolder" (click)="addChild.emit(model)">Add Child</span>
  </div>
  <ul *ngFor="let m of model.children">
    <tree-item [model]="m"></tree-item>
  </ul>
</li>

For above example, parent receives addChild event only from the root tree-item (immediate child). Is it possible to bubble up addChild event from any tree-item? I am using angular 2.0.0-rc.0.

Upvotes: 18

Views: 19194

Answers (3)

tequilacat
tequilacat

Reputation: 757

The closest thing to bubbling the Angular way IMO is using in-place service created by parent and accessed by components as referenced in accepted answer. See Mission Control example.

TL;DR:

  • Create a service providing event observable source
  • inject and provide the service in parent
  • inject the service in child components of the parent - they will access the same instance
  • subscribe to events in parent, emit them in children

The components need not to be direct children of the parent like in the example - the service is accessed deep in hierarchy.

Upvotes: 0

Derek
Derek

Reputation: 103

I came here looking for a solution, and I figured out one on my own. On your tree-item, you can add an event handler like so:

<li>
  <div>{{model.name}}
    <span [hidden]="!isFolder" (click)="addChild.emit(model)">Add Child</span>
  </div>
  <ul *ngFor="let m of model.children">
    <tree-item [model]="m" (yourEventEmitter)="handleEventBubble($event)"></tree-item>
  </ul>
</li>

and in your component.ts:

handleEventBubble(event): void {
  this.yourEventEmitter.emit(event);
}

This will cause the event to emit on the parent element, which passes up the chain all the way up to the root element. You can even define custom bubbling logic by transforming the event before re-emitting it.

Upvotes: 9

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 658205

Events from EventEmitter don't support bubbling.

You can either use element.dispatchEvent() to fire a DOM event that bubbles, or use a shared service like a message bus.

See also https://angular.io/docs/ts/latest/cookbook/component-communication.html

Upvotes: 18

Related Questions