Discussion:
[dart-misc] DOM Event Streams
Pete Blois
2013-01-11 19:15:44 UTC
Permalink
One of our goals for exposing DOM events in Dart is to have them follow the
'best practices' for events- particularly events which are exposed in
places such as your application data model.

The current plan is that DOM events would be exposed as:
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');

Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}

The HtmlStreamProvider class is:
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}

There's basically two parts-

1. The static declaration of the event as an HtmlStreamProvider which
provides a Stream for a DOM event on a specific target. This is only really
used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to the
event stream.

*NOTE*: we will not remove the old APIs until the new APIs have been in &
baked for a while.

Examples of old vs new syntax:

*Listening to an event*
Old:
element.on.click.add((e) {
});
New:
element.onClick.listen((e) {
});

*Capturing an event*
Old:
element.on.click.add((e) {
}, true);
New:
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});

*Listening to a bubbled event*
Old (not really supported):
document.body.$dom_addEventListener('canPlay', (e) {}, false);
New:
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});


*QUESTIONS:*

1. Are you planning on exposing all model events as Streams? By this I
mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.

If you're interested in taking a peek, the CL with the changes is at:
https://codereview.chromium.org/11824072/
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
W. Brian Gourlie
2013-01-11 20:10:26 UTC
Permalink
I really like this change. I also have no problem with the onEventName
naming scheme.
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider which
provides a Stream for a DOM event on a specific target. This is only really
used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in &
baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this I
mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.org/11824072/
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Sean Eagan
2013-01-11 21:15:24 UTC
Permalink
Awesome stuff!
1. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
I'm ok with onEventName, but another suggestions would be to make the
HtmlStreamProvider naming convention slightly more verbose:

Element.clickEventProvider.provideEvent(document.body);

... and then steal the "Event" suffix naming convention for the Streams
themselves:

el.clickEvent.listen(f);

Cheers!
Sean
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
John Evans
2013-01-11 22:50:59 UTC
Permalink
fromEvent?
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
George Moschovitis
2013-01-14 09:23:29 UTC
Permalink
Post by Sean Eagan
Element.clickEventProvider.provideEvent(document.body);
... and then steal the "Event" suffix naming convention for the Streams
el.clickEvent.listen(f);
I like both onEvent *and* your suggestion.
I think I would prefer subscribe() over listen though.

-g.

PS: In general this is a change to the right direction :)
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Sean Eagan
2013-01-14 14:40:39 UTC
Permalink
Sender: misc-dYxm/***@public.gmane.org
X-Received: by 10.180.100.74 with SMTP id ew10mr1931973wib.7.1358174445986;
Mon, 14 Jan 2013 06:40:45 -0800 (PST)
X-BeenThere: misc-dYxm/***@public.gmane.org
Received: by 10.180.87.194 with SMTP id ba2ls1406684wib.6.canary; Mon, 14 Jan
2013 06:40:39 -0800 (PST)
X-Received: by 10.194.108.101 with SMTP id hj5mr38039038wjb.6.1358174439918;
Mon, 14 Jan 2013 06:40:39 -0800 (PST)
X-Received: by 10.194.108.101 with SMTP id hj5mr38039037wjb.6.1358174439907;
Mon, 14 Jan 2013 06:40:39 -0800 (PST)
Received: from mail-we0-f179.google.com (mail-we0-f179.google.com [74.125.82.179])
by mx.google.com with ESMTPS id hq1si10416086wib.9.2013.01.14.06.40.39
(version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
Mon, 14 Jan 2013 06:40:39 -0800 (PST)
Received-SPF: pass (google.com: domain of seaneagan1-***@public.gmane.org designates 74.125.82.179 as permitted sender) client-ip=74.125.82.179;
Received: by mail-we0-f179.google.com with SMTP id r6so2131335wey.10
for <misc-dYxm/***@public.gmane.org>; Mon, 14 Jan 2013 06:40:39 -0800 (PST)
Received: by 10.194.174.234 with SMTP id bv10mr20391416wjc.47.1358174439811;
Mon, 14 Jan 2013 06:40:39 -0800 (PST)
Received: by 10.194.234.102 with HTTP; Mon, 14 Jan 2013 06:40:39 -0800 (PST)
In-Reply-To: <ad2a6016-4268-42f9-b975-f7c1c5412cc8-dYxm/***@public.gmane.org>
X-Original-Sender: seaneagan1-***@public.gmane.org
X-Original-Authentication-Results: mx.google.com; spf=pass (google.com:
domain of seaneagan1-***@public.gmane.org designates 74.125.82.179 as permitted sender)
smtp.mail=seaneagan1-***@public.gmane.org; dkim=pass header.i=@gmail.com
Precedence: list
Mailing-list: list misc-dYxm/***@public.gmane.org; contact misc+owners-dYxm/***@public.gmane.org
List-ID: <misc.dartlang.org>
X-Google-Group-Id: 438608283843
List-Post: <http://groups.google.com/a/dartlang.org/group/misc/post?hl=en-US>, <mailto:misc-dYxm/***@public.gmane.org>
List-Help: <http://support.google.com/a/dartlang.org/bin/topic.py?hl=en-US&topic=25838>,
<mailto:misc+help-dYxm/***@public.gmane.org>
List-Archive: <http://groups.google.com/a/dartlang.org/group/misc/?hl=en-US>
List-Subscribe: <http://groups.google.com/a/dartlang.org/group/misc/subscribe?hl=en-US>,
<mailto:misc+subscribe-dYxm/***@public.gmane.org>
List-Unsubscribe: <http://groups.google.com/a/dartlang.org/group/misc/subscribe?hl=en-US>,
<mailto:googlegroups-manage+438608283843+unsubscribe-/***@public.gmane.org>
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.dart.general/16556>

Another idea, since HtmlStreamProvider (I think it was renamed to
EventStreamProvider) only contains one method, maybe just expose that
method:

Element.clickEventFor(document.body);

then add a typedef:

typedef Stream<T> EventStreamProvider<T>(EventTarget<T> e, {bool
useCapture: false});

which could be used in conjunction with closurizing the methods (for
example Element.clickEventFor above) if/when more generic handling is
needed.

Cheers,
Sean Eagan

On Mon, Jan 14, 2013 at 3:23 AM, George Moschovitis
Post by George Moschovitis
Post by Sean Eagan
Element.clickEventProvider.provideEvent(document.body);
... and then steal the "Event" suffix naming convention for the Streams
el.clickEvent.listen(f);
I like both onEvent *and* your suggestion.
I think I would prefer subscribe() over listen though.
-g.
PS: In general this is a change to the right direction :)
--
http://stackoverflow.com/tags/dart
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Pete Blois
2013-01-14 17:26:37 UTC
Permalink
We definitely should look into simplifying EventStreamProvider down to a
method, though I'm a bit cautious as it may limit future functionality. If
it helps inlining and optimizing the dart2js generated code then that's a
definite win.

In general I think that using the EventStreamProvider is a bit of an edge
case, but it could be useful if we consolidate a number of the duplicated
bubbling events between Element, Window and Document to just Element.
Post by Sean Eagan
Another idea, since HtmlStreamProvider (I think it was renamed to
EventStreamProvider) only contains one method, maybe just expose that
Element.clickEventFor(document.body);
typedef Stream<T> EventStreamProvider<T>(EventTarget<T> e, {bool
useCapture: false});
which could be used in conjunction with closurizing the methods (for
example Element.clickEventFor above) if/when more generic handling is
needed.
Cheers,
Sean Eagan
On Mon, Jan 14, 2013 at 3:23 AM, George Moschovitis
Post by George Moschovitis
Post by Sean Eagan
Element.clickEventProvider.provideEvent(document.body);
... and then steal the "Event" suffix naming convention for the Streams
el.clickEvent.listen(f);
I like both onEvent *and* your suggestion.
I think I would prefer subscribe() over listen though.
-g.
PS: In general this is a change to the right direction :)
--
http://stackoverflow.com/tags/dart
--
http://stackoverflow.com/tags/dart
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Alex Tatumizer
2013-01-14 20:49:31 UTC
Permalink
*Any opinions on naming? Currently the events are exposed as onEventName,
but it's often common to use this naming style for virtual methods. Using
just eventName has a number of conflicts with members. We aren't entirely
thrilled with onEventName.
*
I think "Emitter" is the missing word. It can be
element.clickEmitter.subscribe((e) {
});

But maybe generic version of emitter won't be bad either? Element
implementing EventEmitter directly:
element.subscribe('click', (e) {
});
Sure, you lose type safety here, but code is more succinct (which might be
important for frequently used construct).

Library can support both forms actually.
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Bernhard Pichler
2013-01-12 20:29:10 UTC
Permalink
How do i remove an event listener? Does the "listen" method return some
kind of handle?

The way it works today is really bad. Most people would assume that ...

element.on.click.add(onClickHandler);
element.on.click.remove(onClickHandler);

onClickHandler(e) { }

... just works, but it does not (which is really a shame ... w
ww.dartbug.com/144).

So things can only get better :)
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider which
provides a Stream for a DOM event on a specific target. This is only really
used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in &
baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this I
mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.org/11824072/
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Florian Loitsch
2013-01-12 20:36:03 UTC
Permalink
On Sat, Jan 12, 2013 at 9:29 PM, Bernhard Pichler <
Post by Bernhard Pichler
How do i remove an event listener? Does the "listen" method return some
kind of handle?
Yes. 'listen' returns a Subscription object.
Post by Bernhard Pichler
The way it works today is really bad. Most people would assume that ...
element.on.click.add(onClickHandler);
element.on.click.remove(onClickHandler);
onClickHandler(e) { }
... just works, but it does not (which is really a shame ... w
ww.dartbug.com/144).
This problem would be gone, but in return you need to keep the subscription
object around to be able to cancel the subscription.
Post by Bernhard Pichler
So things can only get better :)
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>**('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider which
provides a Stream for a DOM event on a specific target. This is only really
used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in
& baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(**element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_**addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.**forTarget(document.body).**listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this
I mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.**org/11824072/<https://codereview.chromium.org/11824072/>
--
http://stackoverflow.com/tags/dart
--
Give a man a fire and he's warm for the whole day,
but set fire to him and he's warm for the rest of his life. - Terry
Pratchett
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Bernhard Pichler
2013-01-12 20:45:01 UTC
Permalink
A subscription object is much better then the API we have today.
It should be clear what's going on and does not lead to false assumptions.

Thanks!
Post by Florian Loitsch
On Sat, Jan 12, 2013 at 9:29 PM, Bernhard Pichler <
Post by Bernhard Pichler
How do i remove an event listener? Does the "listen" method return some
kind of handle?
Yes. 'listen' returns a Subscription object.
Post by Bernhard Pichler
The way it works today is really bad. Most people would assume that ...
element.on.click.add(onClickHandler);
element.on.click.remove(onClickHandler);
onClickHandler(e) { }
... just works, but it does not (which is really a shame ... w
ww.dartbug.com/144).
This problem would be gone, but in return you need to keep the
subscription object around to be able to cancel the subscription.
Post by Bernhard Pichler
So things can only get better :)
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>**('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider
which provides a Stream for a DOM event on a specific target. This is only
really used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in
& baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(**element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_**addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.**forTarget(document.body).**listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this
I mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.**org/11824072/<https://codereview.chromium.org/11824072/>
--
http://stackoverflow.com/tags/dart
--
Give a man a fire and he's warm for the whole day,
but set fire to him and he's warm for the rest of his life. - Terry
Pratchett
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Joao Pedrosa
2013-01-13 19:57:54 UTC
Permalink
Hi,
Post by Pete Blois
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
Just adding some example of what it could be if it was not more wasteful,
here's how I do it in my own library:

on({dr_click(ev), dr_mouseup(ev)}) {
storeEventListeners([
'dr_click', dr_click,
'dr_mouseup', dr_mouseup,
]);
}

And that's after adopting some Dart features (named parameters and function
parameter declaration. And a more complex one:

on({focus(ev), blur(ev), dr_enterkey(), dr_edit(), keyup(ev),
keydown(ev), keypress(ev), change(ev), mouseup(ev), mousedown(ev),
paste(ev), input(ev), dr_input()}) {
configureEvents(el, [
"focus", focus,
"blur", blur,
"keyup", keyup,
"keydown", keydown,
"keypress", keypress,
"change", change,
"mouseup", mouseup,
"mousedown", mousedown,
"paste", paste,
"input", input,
]);
if (dr_enterkey != null) {
doConfigureEvent(el, 'keydown', (ev) {
if (ev.keyCode == 13) {
dr_enterkey();
}
});
}
if (dr_edit != null) {
doConfigureEvent(el, 'keyup', (ev) {
if (ev.keyCode == 13) {
dr_edit();
}
});
}
if (dr_input != null) {
doConfigureEvent(el, 'keyup', (ev) {
var kc = ev.keyCode;
if (!DR.highControlKey(kc) && (kc == 8 || kc == 32 || kc >= 46)) {
// 8 - backspace; 32 - spacebar; 46 - delete key.
// 47 and up numbers, characters.
dr_input();
}
});
doConfigureEvent(el, 'paste', (ev) {
DR.timer(dr_input);
});
doConfigureEvent(el, 'input', (ev) => dr_input());
if (DR.isIE) {
doConfigureEvent(el, 'propertychange', dr_input);
}
}
}

I have some conventions going. Events prefixed by "dr_" are custom events
in contrast to the events expected from the DOM.

I fire custom events by using their string names, like so:
callEvent("dr_foo").

I quite like the on(...) API. It can do more work during the registering of
events, but then it all works from a single method and custom widgets can
also enjoy custom events. A single call to on() can register a bunch of
events in one go too. Like so:

id.on(focus: (ev) {
_focus = true;
_blurEventDelayer.stop();
}, blur: (ev) {
_focus = false;
_blurEventDelayer.delay();
hideSelectionFrame();
});

You guys have much more responsibility in creating a generic and general
API. But events are so important, and the more you streamline them, the
better we'll all be.

Thanks a bunch.

Cheers,
Joao
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Alex Tatumizer
2013-01-13 22:00:42 UTC
Permalink
I think the design would be simpler if dart defined standard interface
"EventEmitter" (in the way similar to nodejs and others)
EventEmitter basically has 2 functions
var subscriber=someEventEmitter.subscribe('click',myFunction); // event
type is a string!
someEventEmitter.unsubscribe(subscriber)

or something similar (e.g. shortcut "on" for "subscribe).

A couple of obvious observations:
1) stream IS an EventEmitter (so instead of turning the "stream" of
events into dart Stream, we simply treat Stream as variant of EventEmitter
to begin with)
2) it becomes possible to implement generic functions over ANY event
emitter (I already encountered this problem while trying to translate
circuit concept from javascript to dart).
3) explicit definition of "EventEmitter" simplifies thinking about event
processing (and programming - by implication)

Current design is basically OK, it's just lacking implementation of
abstract EventEmitter in every class which is **informally** an event
emitter already.
How about that?
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Mathieu Breton
2013-01-15 17:48:03 UTC
Permalink
Hello,
I see no reason to upgrade to this new API. "Old" API is elegant, simple
and is a light way to listen an event on a DOM element. The new way doesn't
respect the OO philosophy by using a "dirty" global static method to listen
all DOM events, it's more verbose and not intuitive.
For example, in your Dart editor just type "on" on an element instance and
you see all events "subcrable" on this element, then type "add" and your
handler and it's done. The new way, asks to call a external global class to
listen an event that your not sure that your element supports, unlike to
the "old" API. Moverer the "old" API is similar to the event API of C# that
I find pretty good.

I will be very interrested by a link or a doc to explain this 'best
practices' about event?
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider which
provides a Stream for a DOM event on a specific target. This is only really
used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in &
baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this I
mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.org/11824072/
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Pete Blois
2013-01-15 18:04:18 UTC
Permalink
The static methods are there for listening to bubbling events and capturing
events. 99% of the time you should be able to use the direct stream and not
the static stream provider.

Maintaining the autocomplete list from typing '.on' is one of the primary
reasons the events are being prefixed with 'on'.

One of my primary complaints about the separate class for events (the
.on.eventName syntax) is that the majority of the time when you're exposing
events from custom non-UI classes, you would not use the separate class to
contain events. We did not want DOM events to be exposed in an inconsistent
way with these other events.
Post by Mathieu Breton
I will be very interrested by a link or a doc to explain this 'best
practices' about event?
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Ladislav Thon
2013-01-15 18:40:40 UTC
Permalink
"Old" API is elegant, simple and is a light way to listen an event on a
DOM element.
Unless you want to unsubscribe later...
The new way doesn't respect the OO philosophy by using a "dirty" global
static method to listen all DOM events, it's more verbose and not intuitive.
How exactly *element.onClick.listen(...)* doesn't respect the OO
philosophy, is more verbose and not intuitive?

I think that the special cases that require the static stream provider can
easily be changed to a more succint syntax. (BTW, what is a StreamProvider?
That sounds like a Java name a lot! :-) )

LT
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Ross Smith
2013-01-15 21:16:29 UTC
Permalink
(BTW, what is a StreamProvider? That sounds like a Java name a lot! :-) )
Quite possibly a type of StreamController!? ;)

How does this change affect CustomEvent listening? Will it be:

on['foo'].listen((e) {
});
"Old" API is elegant, simple and is a light way to listen an event on a
Post by Mathieu Breton
DOM element.
Unless you want to unsubscribe later...
Post by Mathieu Breton
The new way doesn't respect the OO philosophy by using a "dirty" global
static method to listen all DOM events, it's more verbose and not intuitive.
How exactly *element.onClick.listen(...)* doesn't respect the OO
philosophy, is more verbose and not intuitive?
I think that the special cases that require the static stream provider can
easily be changed to a more succint syntax. (BTW, what is a StreamProvider?
That sounds like a Java name a lot! :-) )
LT
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Pete Blois
2013-01-15 21:46:41 UTC
Permalink
Agreed, naming is not ideal. I'd like to make this callable to mimic the
syntax of the typedef mentioned above, but avoid potential limitations in
the future.

We're working on allowing subclassing of Element, so ideally custom events
are exposed the same way as the rest of the DOM events.

For listening to your custom event further up the tree, it falls into the
'bubbling events' case I mentioned above-
*Listening to a bubbled event*
Old (not really supported):
document.body.$dom_addEventListener('canPlay', (e) {}, false);
New:
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});

Note that this can also be used for declaring events anywhere-
class Something {
static const EventStreamProvider<SomeEvent> someEvent = const
EventStreamProvider<SomeEvent>('somethinghappened');
}

Then to listen to that:
Something.someEvent.forTarget(element).listen(...)

Though we could possibly provide a Stream getter on EventTarget such as:
Stream<Event> getEventStream(String eventType, {bool useCapture});

The benefit of the static providers is that it gives more clarity as to the
event type and avoids potential typos in strings.
s
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Ross Smith
2013-01-16 00:33:35 UTC
Permalink
Post by Pete Blois
We're working on allowing subclassing of Element, so ideally custom
events are exposed the same way as the rest of the DOM events.

Great! I'm looking forward to that, thanks for the info.
Post by Pete Blois
Agreed, naming is not ideal. I'd like to make this callable to mimic the
syntax of the typedef mentioned above, but avoid potential limitations in
the future.
We're working on allowing subclassing of Element, so ideally custom events
are exposed the same way as the rest of the DOM events.
For listening to your custom event further up the tree, it falls into the
'bubbling events' case I mentioned above-
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
Note that this can also be used for declaring events anywhere-
class Something {
static const EventStreamProvider<SomeEvent> someEvent = const
EventStreamProvider<SomeEvent>('somethinghappened');
}
Something.someEvent.forTarget(element).listen(...)
Stream<Event> getEventStream(String eventType, {bool useCapture});
The benefit of the static providers is that it gives more clarity as to
the event type and avoids potential typos in strings.
s
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Tomas Polovincak
2013-01-23 02:10:14 UTC
Permalink
How I can emit custom events when old API with on[eventName].dispatch will
be removed?
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Kevin Kellogg
2013-01-23 03:02:39 UTC
Permalink
How I can emit custom events when old API with on[eventName].dispatch will
be removed?
Dispatch is replaced with "add"ing your event to a StreamController
(StreamController implements StreamSink). Expose StreamController#stream to
listen for events.

Kevin
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Tomas Polovincak
2013-01-23 03:10:52 UTC
Permalink
thanks for your help.
Post by Kevin Kellogg
How I can emit custom events when old API with on[eventName].dispatch
will be removed?
Dispatch is replaced with "add"ing your event to a StreamController
(StreamController implements StreamSink). Expose StreamController#stream to
listen for events.
Kevin
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Greg Lusk
2013-01-23 18:40:14 UTC
Permalink
Could someone provide a quick code snippet on how to register a custom
event using the new API?

Thanks in advance,

Greg
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider which
provides a Stream for a DOM event on a specific target. This is only really
used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in &
baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this I
mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.org/11824072/
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Pete Blois
2013-01-23 18:46:50 UTC
Permalink
Take a look at my comment further up this thread and let me know if there
are still some questions.
Post by Greg Lusk
Could someone provide a quick code snippet on how to register a custom
event using the new API?
Thanks in advance,
Greg
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider which
provides a Stream for a DOM event on a specific target. This is only really
used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in
& baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this
I mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.org/11824072/
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Greg Lusk
2013-01-23 19:43:08 UTC
Permalink
Pete,

Using the old event syntax, I can do something like this to dispatch and
raise a custom event to a DOM object dynamically:

query('#btn').on['clickMe'].dispatch(new CustomEvent('clickMe', true, true,
new ClickMeEventArgs("value1", "value2")));

So I'm looking for the equivalent syntax using the new API. I need to be
able to dynamically attach and raise events to DOM (and custom) objects and
let the DOM handle the handler invocation so that I don't have to code a
separate event handling mechanism. Correspondingly, I need to allow other
elements to listen for these dynamically-added events. We have been able
to achieve this goal using the old API, but haven't yet been able to do so
using the new one. Having to bake in "hard-coded" events at design time is
not always an option in our application model.
Post by Pete Blois
Take a look at my comment further up this thread and let me know if there
are still some questions.
Post by Greg Lusk
Could someone provide a quick code snippet on how to register a custom
event using the new API?
Thanks in advance,
Greg
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider
which provides a Stream for a DOM event on a specific target. This is only
really used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in
& baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this
I mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.org/11824072/
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Pete Blois
2013-01-23 19:51:30 UTC
Permalink
We haven't yet added the dispatch method for dispatching events, the old
syntax will continue to work and will work correctly with the new streams.

Right now the leading API proposal for dispatching events is to move closer
to the standard DOM api-
query('#btn').dispatchEvent(new CustomEvent('clickMe', true, true, new
ClickMeEventArgs("value1", "value2")));

Also note that we're updating event constructors to use named parameters
for most of the arguments, so you're code here would look more like:
query('#btn').dispatchEvent(new CustomEvent('clickMe', detail: new
ClickMeEventArgs("value1", "value2")));
Post by Greg Lusk
Pete,
Using the old event syntax, I can do something like this to dispatch and
query('#btn').on['clickMe'].dispatch(new CustomEvent('clickMe', true,
true, new ClickMeEventArgs("value1", "value2")));
So I'm looking for the equivalent syntax using the new API. I need to be
able to dynamically attach and raise events to DOM (and custom) objects and
let the DOM handle the handler invocation so that I don't have to code a
separate event handling mechanism. Correspondingly, I need to allow other
elements to listen for these dynamically-added events. We have been able
to achieve this goal using the old API, but haven't yet been able to do so
using the new one. Having to bake in "hard-coded" events at design time is
not always an option in our application model.
Post by Pete Blois
Take a look at my comment further up this thread and let me know if there
are still some questions.
Post by Greg Lusk
Could someone provide a quick code snippet on how to register a custom
event using the new API?
Thanks in advance,
Greg
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider
which provides a Stream for a DOM event on a specific target. This is only
really used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been
in & baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By
this I mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.org/11824072/
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Greg Lusk
2013-01-23 19:56:06 UTC
Permalink
Excellent! That's what I needed to know!

On a related note, is there any thought being given to being able to
strongly type the "detail" property of the CustomEvent class when you
receive it in the handler? I understand that it's being serialized and then
deserialized into a LinkedHashMap for marshaling of events between
Isolates, but it does make it difficult on the handler to not be able to
obtain the "detail" property in its original object form.

Thanks!
Post by Pete Blois
We haven't yet added the dispatch method for dispatching events, the old
syntax will continue to work and will work correctly with the new streams.
Right now the leading API proposal for dispatching events is to move
closer to the standard DOM api-
query('#btn').dispatchEvent(new CustomEvent('clickMe', true, true, new
ClickMeEventArgs("value1", "value2")));
Also note that we're updating event constructors to use named parameters
query('#btn').dispatchEvent(new CustomEvent('clickMe', detail: new
ClickMeEventArgs("value1", "value2")));
Post by Greg Lusk
Pete,
Using the old event syntax, I can do something like this to dispatch and
query('#btn').on['clickMe'].dispatch(new CustomEvent('clickMe', true,
true, new ClickMeEventArgs("value1", "value2")));
So I'm looking for the equivalent syntax using the new API. I need to be
able to dynamically attach and raise events to DOM (and custom) objects and
let the DOM handle the handler invocation so that I don't have to code a
separate event handling mechanism. Correspondingly, I need to allow other
elements to listen for these dynamically-added events. We have been able
to achieve this goal using the old API, but haven't yet been able to do so
using the new one. Having to bake in "hard-coded" events at design time is
not always an option in our application model.
Post by Pete Blois
Take a look at my comment further up this thread and let me know if
there are still some questions.
Post by Greg Lusk
Could someone provide a quick code snippet on how to register a custom
event using the new API?
Thanks in advance,
Greg
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them
follow the 'best practices' for events- particularly events which are
exposed in places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider
which provides a Stream for a DOM event on a specific target. This is only
really used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access
to the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been
in & baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By
this I mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.org/11824072/
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Pete Blois
2013-01-23 20:00:41 UTC
Permalink
We'd like to allow subclassing of Event classes which would allow arbitrary
properties. We have some work to do, but the goal is to get this at the
same time as subclassing of Element.
Post by Greg Lusk
Excellent! That's what I needed to know!
On a related note, is there any thought being given to being able to
strongly type the "detail" property of the CustomEvent class when you
receive it in the handler? I understand that it's being serialized and then
deserialized into a LinkedHashMap for marshaling of events between
Isolates, but it does make it difficult on the handler to not be able to
obtain the "detail" property in its original object form.
Thanks!
Post by Pete Blois
We haven't yet added the dispatch method for dispatching events, the old
syntax will continue to work and will work correctly with the new streams.
Right now the leading API proposal for dispatching events is to move
closer to the standard DOM api-
query('#btn').dispatchEvent(ne**w CustomEvent('clickMe', true,** true,
new ClickMeEventArgs("**value1", "value2")));
Also note that we're updating event constructors to use named parameters
query('#btn').dispatchEvent(ne**w CustomEvent('clickMe', **detail: new
ClickMeEventArgs("**value1", "value2")));
Post by Greg Lusk
Pete,
Using the old event syntax, I can do something like this to dispatch and
query('#btn').on['clickMe'].d**ispatch(new CustomEvent('clickMe', true,
true, new ClickMeEventArgs("value1", "value2")));
So I'm looking for the equivalent syntax using the new API. I need to be
able to dynamically attach and raise events to DOM (and custom) objects and
let the DOM handle the handler invocation so that I don't have to code a
separate event handling mechanism. Correspondingly, I need to allow other
elements to listen for these dynamically-added events. We have been able
to achieve this goal using the old API, but haven't yet been able to do so
using the new one. Having to bake in "hard-coded" events at design time is
not always an option in our application model.
Post by Pete Blois
Take a look at my comment further up this thread and let me know if
there are still some questions.
Post by Greg Lusk
Could someone provide a quick code snippet on how to register a custom
event using the new API?
Thanks in advance,
Greg
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them
follow the 'best practices' for events- particularly events which are
exposed in places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>**('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider
which provides a Stream for a DOM event on a specific target. This is only
really used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access
to the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been
in & baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(**element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_**addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.**forTarget(document.body).**listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By
this I mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.**org/11824072/<https://codereview.chromium.org/11824072/>
--
http://stackoverflow.com/tags/dart
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Greg Lusk
2013-01-23 20:01:54 UTC
Permalink
That would be a great feature. +1 for adding it.
Post by Pete Blois
We'd like to allow subclassing of Event classes which would allow
arbitrary properties. We have some work to do, but the goal is to get this
at the same time as subclassing of Element.
Post by Greg Lusk
Excellent! That's what I needed to know!
On a related note, is there any thought being given to being able to
strongly type the "detail" property of the CustomEvent class when you
receive it in the handler? I understand that it's being serialized and then
deserialized into a LinkedHashMap for marshaling of events between
Isolates, but it does make it difficult on the handler to not be able to
obtain the "detail" property in its original object form.
Thanks!
Post by Pete Blois
We haven't yet added the dispatch method for dispatching events, the old
syntax will continue to work and will work correctly with the new streams.
Right now the leading API proposal for dispatching events is to move
closer to the standard DOM api-
query('#btn').dispatchEvent(ne**w CustomEvent('clickMe', true,** true,
new ClickMeEventArgs("**value1", "value2")));
Also note that we're updating event constructors to use named parameters
query('#btn').dispatchEvent(ne**w CustomEvent('clickMe', **detail: new
ClickMeEventArgs("**value1", "value2")));
Post by Greg Lusk
Pete,
Using the old event syntax, I can do something like this to dispatch
query('#btn').on['clickMe'].d**ispatch(new CustomEvent('clickMe', true
, true, new ClickMeEventArgs("value1", "value2")));
So I'm looking for the equivalent syntax using the new API. I need to
be able to dynamically attach and raise events to DOM (and custom) objects
and let the DOM handle the handler invocation so that I don't have to code
a separate event handling mechanism. Correspondingly, I need to allow other
elements to listen for these dynamically-added events. We have been able
to achieve this goal using the old API, but haven't yet been able to do so
using the new one. Having to bake in "hard-coded" events at design time is
not always an option in our application model.
Post by Pete Blois
Take a look at my comment further up this thread and let me know if
there are still some questions.
Post by Greg Lusk
Could someone provide a quick code snippet on how to register a
custom event using the new API?
Thanks in advance,
Greg
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them
follow the 'best practices' for events- particularly events which are
exposed in places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>**('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider
which provides a Stream for a DOM event on a specific target. This is only
really used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access
to the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have
been in & baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(**element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_**addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.**forTarget(document.body).**listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By
this I mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.**org/11824072/<https://codereview.chromium.org/11824072/>
--
http://stackoverflow.com/tags/dart
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Tomas Polovincak
2013-01-24 00:31:48 UTC
Permalink
as Kevin Kellogg write StreamController works fine:

StreamController<CustomEvent> sc = new StreamController.multiSubscription();
sc.listen((CustomEvent event) {
print("listener #1");
});
sc.listen((CustomEvent event) {
print("listener #2");
});
sc.add(new CustomEvent('clickMe', true, true, new ClickMeEventArgs("value1",
"value2")));
Post by Greg Lusk
Could someone provide a quick code snippet on how to register a custom
event using the new API?
Thanks in advance,
Greg
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider which
provides a Stream for a DOM event on a specific target. This is only really
used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in
& baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this
I mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.org/11824072/
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Greg Lusk
2013-01-24 00:36:14 UTC
Permalink
Thanks, Tomas.
Post by Tomas Polovincak
StreamController<CustomEvent> sc = new StreamController.multiSubscription
();
sc.listen((CustomEvent event) {
print("listener #1");
});
sc.listen((CustomEvent event) {
print("listener #2");
});
sc.add(new CustomEvent('clickMe', true, true, new ClickMeEventArgs(
"value1","value2")));
Could someone provide a quick code snippet on how to register a custom
event using the new API?
Thanks in advance,
Greg
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>**('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider which
provides a Stream for a DOM event on a specific target. This is only really
used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in &
baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(**element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_**addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.**forTarget(document.body).**listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this I
mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.**org/11824072/<https://codereview.chromium.org/11824072/>
--
http://stackoverflow.com/tags/dart
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Pete Blois
2013-01-24 00:53:09 UTC
Permalink
Not that going through a StreamController is a bit misleading for DOM
events, as it's not actually going through the DOM (and things like
bubbling will not take effect).

If you do use a StreamController, I'd recommend something other than
CustomEvent (or any other DOM event) for the data, for clarity.


On Wed, Jan 23, 2013 at 4:31 PM, Tomas Polovincak <
Post by Tomas Polovincak
StreamController<CustomEvent> sc = new StreamController.multiSubscription
();
sc.listen((CustomEvent event) {
print("listener #1");
});
sc.listen((CustomEvent event) {
print("listener #2");
});
sc.add(new CustomEvent('clickMe', true, true, new ClickMeEventArgs(
"value1","value2")));
Post by Greg Lusk
Could someone provide a quick code snippet on how to register a custom
event using the new API?
Thanks in advance,
Greg
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>**('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider
which provides a Stream for a DOM event on a specific target. This is only
really used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in
& baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(**element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_**addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.**forTarget(document.body).**listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this
I mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.**org/11824072/<https://codereview.chromium.org/11824072/>
--
http://stackoverflow.com/tags/dart
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Kevin Kellogg
2013-01-24 04:30:41 UTC
Permalink
Good point. I should have been more mindful of the context of this thread.

Tomas: "sc.listen" should be "sc.stream.listen". StreamController soon will
not extend Stream.
Post by Pete Blois
Not that going through a StreamController is a bit misleading for DOM
events, as it's not actually going through the DOM (and things like
bubbling will not take effect).
If you do use a StreamController, I'd recommend something other than
CustomEvent (or any other DOM event) for the data, for clarity.
Post by Tomas Polovincak
StreamController<CustomEvent> sc = new StreamController.
multiSubscription();
sc.listen((CustomEvent event) {
print("listener #1");
});
sc.listen((CustomEvent event) {
print("listener #2");
});
sc.add(new CustomEvent('clickMe', true, true, new ClickMeEventArgs(
"value1","value2")));
Post by Greg Lusk
Could someone provide a quick code snippet on how to register a custom
event using the new API?
Thanks in advance,
Greg
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>**('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider
which provides a Stream for a DOM event on a specific target. This is only
really used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been
in & baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(**element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_**addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.**forTarget(document.body).**listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By
this I mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.**org/11824072/<https://codereview.chromium.org/11824072/>
--
http://stackoverflow.com/tags/dart
--
Consider asking HOWTO questions at Stack Overflow: http://stackoverflow.com/tags/dart
Thiện Mẫn Hoàng
2013-09-10 09:24:33 UTC
Permalink
This is just too complicated
Element.clickEvent.forTarget(element, useCapture: true).listen((e) {
});

What about element.onClick.capture((e) {...});?
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider which
provides a Stream for a DOM event on a specific target. This is only really
used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in &
baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this I
mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.org/11824072/
--
For other discussions, see https://groups.google.com/a/dartlang.org/

For HOWTO questions, visit http://stackoverflow.com/tags/dart

To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+unsubscribe-dYxm/***@public.gmane.org
Pete Blois
2013-09-10 15:56:19 UTC
Permalink
That works. I opened https://code.google.com/p/dart/issues/detail?id=13214
Post by Thiện Mẫn Hoàng
This is just too complicated
Element.clickEvent.forTarget(element, useCapture: true).listen((e) {
});
What about element.onClick.capture((e) {...});?
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>**('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider which
provides a Stream for a DOM event on a specific target. This is only really
used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in
& baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(**element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_**addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.**forTarget(document.body).**listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this
I mean something like backbone.js-style events<http://backbonejs.org/#Events>.
Our goal for DOM events is to be consistent with the dominant data event
model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.**org/11824072/<https://codereview.chromium.org/11824072/>
--
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to http://www.dartbug.com/new
--
For other discussions, see https://groups.google.com/a/dartlang.org/

For HOWTO questions, visit http://stackoverflow.com/tags/dart

To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+unsubscribe-dYxm/***@public.gmane.org
DoHyung Kim
2015-06-22 10:41:23 UTC
Permalink
Sorry for coming quite late on this issue (seems already too late, but I
began to look into Dart since the end of the last year).

But, it is quite weird to have both listen and capture on Stream.
Stream.capture can't benefit from various filtering and transformative
methods available on Stream (can't also from async/await). For instance,
once map or where is called, the returned Stream won't be a ElementStream
anymore. It's my impression that Stream is not designed to have additional
subscription method like Stream.capture.

I know that I can get separate Streams for events in bubbling and capturing
phases via separate APIs, but it would have been better to have separate
event streams and accompanying getters for bubbling and capturing events.

Am I missing some context?

Thanks.
Post by Pete Blois
That works. I opened https://code.google.com/p/dart/issues/detail?id=13214
Post by Thiện Mẫn Hoàng
This is just too complicated
Element.clickEvent.forTarget(element, useCapture: true).listen((e) {
});
What about element.onClick.capture((e) {...});?
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider
which provides a Stream for a DOM event on a specific target. This is only
really used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been in
& baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By this
I mean something like backbone.js-style events
<http://backbonejs.org/#Events>. Our goal for DOM events is to be
consistent with the dominant data event model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.org/11824072/
--
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to http://www.dartbug.com/new
--
For other discussions, see https://groups.google.com/a/dartlang.org/

For HOWTO questions, visit http://stackoverflow.com/tags/dart

To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
'Pete Blois' via Dart Misc
2015-06-22 17:25:01 UTC
Permalink
Streams are indeed not really sub-classable but from the API complexity
standpoint having separate members for capture is too much. IMHO desiring
API extensions such as 'matches' is perfectly reasonable- an ideal scenario
for extension methods!

The mere presence of those members has a non-trivial effect on dart2js
compilation size, I'd be hesitant to double them.
Post by DoHyung Kim
Sorry for coming quite late on this issue (seems already too late, but I
began to look into Dart since the end of the last year).
But, it is quite weird to have both listen and capture on Stream.
Stream.capture can't benefit from various filtering and transformative
methods available on Stream (can't also from async/await). For instance,
once map or where is called, the returned Stream won't be a ElementStream
anymore. It's my impression that Stream is not designed to have additional
subscription method like Stream.capture.
I know that I can get separate Streams for events in bubbling and
capturing phases via separate APIs, but it would have been better to have
separate event streams and accompanying getters for bubbling and capturing
events.
Am I missing some context?
Thanks.
Post by Pete Blois
That works. I opened
https://code.google.com/p/dart/issues/detail?id=13214
Post by Thiện Mẫn Hoàng
This is just too complicated
Element.clickEvent.forTarget(element, useCapture: true).listen((e) {
});
What about element.onClick.capture((e) {...});?
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them follow
the 'best practices' for events- particularly events which are exposed in
places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider
which provides a Stream for a DOM event on a specific target. This is only
really used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access to
the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been
in & baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By
this I mean something like backbone.js-style events
<http://backbonejs.org/#Events>. Our goal for DOM events is to be
consistent with the dominant data event model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.org/11824072/
--
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to
http://www.dartbug.com/new
--
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to http://www.dartbug.com/new
--
For other discussions, see https://groups.google.com/a/dartlang.org/

For HOWTO questions, visit http://stackoverflow.com/tags/dart

To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
'Justin Fagnani' via Dart Misc
2015-06-22 21:23:37 UTC
Permalink
On Mon, Jun 22, 2015 at 10:25 AM, 'Pete Blois' via Dart Misc <
Post by 'Pete Blois' via Dart Misc
Streams are indeed not really sub-classable but from the API complexity
standpoint having separate members for capture is too much. IMHO desiring
API extensions such as 'matches' is perfectly reasonable- an ideal scenario
for extension methods!
The mere presence of those members has a non-trivial effect on dart2js
compilation size, I'd be hesitant to double them.
You don't have to double, you can produce a new Stream:

class ElementStream<T> {
Stream<T> captureStream;
}

similar to matches()
Post by 'Pete Blois' via Dart Misc
Post by DoHyung Kim
Sorry for coming quite late on this issue (seems already too late, but I
began to look into Dart since the end of the last year).
But, it is quite weird to have both listen and capture on Stream.
Stream.capture can't benefit from various filtering and transformative
methods available on Stream (can't also from async/await). For instance,
once map or where is called, the returned Stream won't be a ElementStream
anymore. It's my impression that Stream is not designed to have additional
subscription method like Stream.capture.
I know that I can get separate Streams for events in bubbling and
capturing phases via separate APIs, but it would have been better to have
separate event streams and accompanying getters for bubbling and capturing
events.
Am I missing some context?
Thanks.
Post by Pete Blois
That works. I opened
https://code.google.com/p/dart/issues/detail?id=13214
Post by Thiện Mẫn Hoàng
This is just too complicated
Element.clickEvent.forTarget(element, useCapture: true).listen((e) {
});
What about element.onClick.capture((e) {...});?
Post by Pete Blois
One of our goals for exposing DOM events in Dart is to have them
follow the 'best practices' for events- particularly events which are
exposed in places such as your application data model.
class Element {
static const HtmlStreamProvider<MouseEvent> clickEvent =
const HtmlStreamProvider<MouseEvent>('click');
Stream<MouseEvent> get onClick => clickEvent.forTarget(this);
}
class HtmlStreamProvider<T extends Event> {
const HtmlStreamProvider(String eventType);
Stream<T> forTarget(EventTarget e, {bool useCapture: false})
}
There's basically two parts-
1. The static declaration of the event as an HtmlStreamProvider
which provides a Stream for a DOM event on a specific target. This is only
really used for bubbling DOM events.
2. A Stream<> getter on the object instance to allow easy access
to the event stream.
*NOTE*: we will not remove the old APIs until the new APIs have been
in & baked for a while.
*Listening to an event*
element.on.click.add((e) {
});
element.onClick.listen((e) {
});
*Capturing an event*
element.on.click.add((e) {
}, true);
Element.clickEvent.forTarget(element, useCapture:true).listen((e) {
});
*Listening to a bubbled event*
document.body.$dom_addEventListener('canPlay', (e) {}, false);
MediaElement.canPlayEvent.forTarget(document.body).listen((e) {
});
*QUESTIONS:*
1. Are you planning on exposing all model events as Streams? By
this I mean something like backbone.js-style events
<http://backbonejs.org/#Events>. Our goal for DOM events is to be
consistent with the dominant data event model.
2. Any opinions on naming? Currently the events are exposed as
onEventName, but it's often common to use this naming style for virtual
methods. Using just eventName has a number of conflicts with members. We
aren't entirely thrilled with onEventName.
https://codereview.chromium.org/11824072/
--
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to
http://www.dartbug.com/new
--
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to http://www.dartbug.com/new
--
For other discussions, see https://groups.google.com/a/dartlang.org/
For HOWTO questions, visit http://stackoverflow.com/tags/dart
To file a bug report or feature request, go to http://www.dartbug.com/new
To unsubscribe from this group and stop receiving emails from it, send an
--
For other discussions, see https://groups.google.com/a/dartlang.org/

For HOWTO questions, visit http://stackoverflow.com/tags/dart

To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
DoHyung Kim
2015-06-22 23:32:43 UTC
Permalink
Thank you for the brief of underlying rationale. Practically the current API works w/o problems.

BTW, you mentioned dart2js generated code size. Isn't tree shaking supposed to remove unused fields? Just out of curiosity.
--
For other discussions, see https://groups.google.com/a/dartlang.org/

For HOWTO questions, visit http://stackoverflow.com/tags/dart

To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
Continue reading on narkive:
Loading...