Search code examples
dartdart-polymer

PolymerElement - capture onClick events to pass to CustomEvent


Building a single page app using Polymer.Dart, I was thinking the best way of achieving a two way EventBus

From the child <polymer-element> I will use fire and asyncFire. From the parent <polymer-element> I will capture all events using window.on['*'].listen.

As the <polymer-element> is encapsulated, no events will bubble up outside of the element itself.

import 'package:polymer/polymer.dart';
import 'dart:html';

@CustomTag('click-counter')
class ClickCounter extends PolymerElement {
  @published int count = 0;

  ClickCounter.created() : super.created() {
    this.shadowRoot.addEventListener('click', (e) {
      if(e.target is AnchorElement) {
        AnchorElement anchor = e.target;
        this.asyncFire('ce', detail: "Anchor ${anchor.pathname}", canBubble: true);
        e.preventDefault();
      }
    }, true);
  }

  void increment(Event event, var detail, Node target) {
    count++;
    this.asyncFire('ce', detail: "Click...$count..", canBubble: true);
  }
}

For example, in order to catch all on-click events, and passing to fire and asyncFire, is the most efficient way to capture all on-click events using this.shadowRoot.addEventListener and pass to fire or asyncFire, or is there a better, more efficient way to listen on the <polymer-element> itself.


Solution

  • I'm not sure what the exact question here is, but the technique you're using is fine, and it's what I do to work around event retargeting.

    Just to clarify a few things, events do bubble out of shadow trees, but when they cross the shadow boundary they are retargeted to the shadow host. The problem with click events is that the target property is not part of the event, but part of the anchor tag, so when the event is retargeted you lose access to the property.

    Also, I don't think on['*'] works. I don't see any documentation on it, and some testing for it doesn't work. Instead, simply having an element enclose your elements that any node can listen on for any event type should work well as broadcaster. If you're trying to pipe events to another frame, I'd configure the event bus to forward a certain set of event types.