3

Can I pass not only String attributes but also object references to an event handler?

Sample gwt_contacts from https://github.com/sethladd/dart-polymer-dart-examples:

contacts_view.html:

<div id="contact-list">
  <template repeat="{{contacts}}">
    <div>
      <input type="checkbox">
      <span on-click="selectContact" data-id="{{id}}">{{name}}</span>
    </div>
  </template>
</div>

handler in contacts_view.dart

void selectContact(MouseEvent event, var detail, SpanElement target) {
  String id = target.attributes["data-id"];
  selectedContact = contacts.firstWhere((Contact contact) => contact.id == id);
}

How can I pass the contact reference instead of the ID?

similar question: How do I pass arbitrary data to a click event handler function from a Dart polymer web component

CHANGED:

With the hint of Christophe Herreman I added a new element:

html:

<polymer-element name="contact-view-item">
  <template>
    <span on-click="select">{{contact.name}}</span>
  </template>
</polymer-element>

dart:

@CustomTag("contact-view-item")
class ContactViewItem extends PolymerElement {
  @observable @published Contact contact;

  void select(MouseEvent event, var detail, var target) {
    dispatchEvent(new CustomEvent("contactselected", detail: contact));
  }
}

and changed the list to:

<div id="contact-list">
  <template repeat="{{contact in contacts}}">
    <div>
      <input type="checkbox">
      <contact-view-item contact="{{contact}}" on-contactselected="contactSelectedHandler"></contact-view-item>
    </div>
  </template>
</div>

and added the handler to ContactsView:

void contactSelectedHandler(CustomEvent event) {
  selectedContact = event.detail;
}

But dispatching the custom event will throw an error:

Uncaught Error: unsupported object type for conversion
Exception: unsupported object type for conversion
undefined (undefined:0:0)

The connection seems to be fine, because if I don't pass contact as detail than contactSelectedHandler will be called, but detail is - of course - null.

Community
  • 1
  • 1

1 Answers1

2

I don't think that is possible declaratively from within the HTML definition. You can dispatch an object in the detail property of a CustomEvent, when you dispatch it from the element class. Note that the detail property is actually just a reference to event.detail when event is a CustomEvent. If not, the detail property is null.

Component definition

<div id="contact-list">
  <template repeat="{{contacts}}">
    <div>
      <input type="checkbox">
      <span on-click="contact_clickHandler" data-id="{{id}}">{{name}}</span>
    </div>
  </template>
</div>
void contact_clickHandler(MouseEvent event, var detail, SpanElement target) {
  String id = target.attributes["data-id"];
  Contact contact = contacts.firstWhere((Contact c) => c.id == id);
  dispatchEvent(new CustomEvent("contactselected", detail: selectedContact));
}

Component usage

<contact-list on-contactselected="contactList_contactSelectedHandler"></contact-list>
void contactList_contactSelectedHandler(CustomEvent event) {
  var contact = event.detail;
  // do something with selected contact
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
Christophe Herreman
  • 15,895
  • 9
  • 58
  • 86
  • I thought of a solution create a "child" polymer element, pass the object as attribute and propagate the event to the parent with this object. Do you mean such a solution? But I don't know how to implement this correct – Gerald Leeb Oct 12 '13 at 18:15
  • I would just dispatch the custom event containing the selected contact from the element class. The view that uses the component can then simply listen for the custom event and get the contact from the event detail. I added a code example to the answer. – Christophe Herreman Oct 12 '13 at 18:37
  • changed the question - please see above – Gerald Leeb Oct 12 '13 at 19:27
  • There seems to be an open issue regarding this: https://code.google.com/p/dart/issues/detail?id=11192 – Christophe Herreman Oct 12 '13 at 21:42