6

如果我编写以下 Dart 代码,我怎么知道哪个点击处理程序首先发生?

main() {
  var button = new ButtonElement();
  var stream = button.onClick.asBroadcastStream();

  stream.listen(clickHandler1);
  stream.listen(clickHandler2);
}

假设我在其他代码中,对前两个单击处理程序一无所知,但我注册了另一个。

  • 我可以知道流有两个听众吗?
  • 我可以暂停或取消所有其他订阅者吗?
  • 如果我button.onClick.asBroadcastStream()在其他地方再次写入,它是否指向与中使用的流相同的流main
  • 我可以在其中一个处理程序中说不要将事件传递给另一个广播侦听器吗?那是消费者吗?
4

2 回答 2

6

假设我在其他代码中,对前两个单击处理程序一无所知,但我注册了另一个。

我可以知道流有两个听众吗?

不,你不能。您可以扩展流类或包装它并自己提供此功能,但这感觉不是一个好的设计选择,因为我认为听众不应该了解其他听众。你到底想做什么?也许有比让听众了解彼此更好的方法。

我可以暂停或取消所有其他订阅者吗?

您只能取消/暂停/恢复您正在处理的订阅者。同样,您可能不应该接触其他侦听器,但我想您可以包装/扩展 Stream 类以具有此行为。

如果我在别处再次写 button.onClick.asBroadcastStream() ,它是否指向与 main 中使用的相同流?

不,至少不是在当前版本的 SDK 中。因此,不幸的是,您需要在某处存储对该广播流的引用并引用它,因为asBroadcastStream()多次调用不会产生您可能期望的结果。(注意:至少基于快速测试:http ://d.pr/i/Ip0K虽然文档似乎表明不同,但当我找到时间时,我还没有进行更多测试)。

我可以在其中一个处理程序中说不要将事件传递给另一个广播侦听器吗?

好吧,stopPropagation()在 HTML 领域中,这意味着该事件不会传播到其他元素,但它可能不是您想要的。

为了能够停止在其他侦听器中触发的事件,需要有一个调用侦听器的顺序。我相信顺序是那些听众的注册顺序。从设计的角度来看,我认为允许听众取消/暂停其他人不是一个好主意。

HTML 中的事件传播是有意义的,因为它是关于层次结构的,但在这里我们没有(即使在 HTML 中的事件的情况下,单个元素也可以有多个侦听器)。

没有办法为听众分配权重或定义重要性顺序,因此没有办法停止事件也就不足为奇了。

与其让听众相互了解并相互操纵,也许你应该尝试考虑另一种方法来解决你的问题(不管是什么)。

那是消费者吗?

StreamConsumer如果您想允许其他流通过管道传输到您的类中,这只是您可以实现的一个类。

于 2013-05-01T11:15:49.747 回答
1

我可以知道流有两个听众吗?

不,您有一个包装 DOM 事件处理的“流”。没有这样的功能。

我可以暂停或取消所有其他订阅者吗?

查看Event.stopPropagation()Event.stopImmediatePropagation(),可能还有Event.preventDefault()

如果我在别处再次写 button.onClick.asBroadcastStream() ,它是否指向与 main 中使用的相同流?

[更新] 不,当前的实现不会给你相同的 Stream 返回,因为onClickgetter 每次调用它都会返回一个新的流。但是,返回的流已经是一个广播流,所以你不应该调用asBroadcastStream()它。如果你这样做了,你只会得到对同一个对象的引用。

Stream<T> asBroadcastStream() => this;

我可以在其中一个处理程序中说不要将事件传递给另一个广播侦听器吗?那是消费者吗?

同样,看看Event.stopPropagation()Event.stopImmediatePropagation(),可能还有Event.preventDefault()

于 2013-05-02T23:30:37.840 回答