2013-04-20 2 views
6

Если я напишу следующий код Dart, как узнать, что происходит с первым обработчиком?В Dart, если я слушаю событие click с двумя слушателями, как узнать, что происходит первым?

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

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

Допустим, я в другом коде, который ничего не знает о первых двух обработчиков клик не знаю, но я зарегистрировать еще один.

  • Могу ли я узнать, что в потоке есть два слушателя?
  • Могу ли я приостановить или отменить всех других подписчиков?
  • Если я пишу button.onClick.asBroadcastStream() еще раз в другом месте, он указывает на тот же поток, который использовался в main?
  • Могу ли я сказать в одном из обработчиков, чтобы не передавать событие другому слушателю вещания? Это потребитель?

ответ

6

Допустим, я в другом коде, который ничего не знает о первых два обработчиков щелчка не знаю, но я зарегистрировать еще один.

Могу ли я узнать, что в потоке есть два слушателя?

Нет, вы не можете. Вы можете расширить класс потока или обернуть его и предоставить эту функцию самостоятельно, но это не похоже на хороший выбор дизайна, потому что я не думаю, что слушатель должен знать о других слушателях. Что вы пытаетесь сделать точно? Возможно, есть лучший способ, чем позволить слушателям узнать друг о друге.

Могу ли я приостановить или отменить всех других подписчиков?

cancel/pause/resume Только подписчик, с которым имеете дело. Опять же, вы, вероятно, не должны прикасаться к другим слушателям, но я думаю, вы могли бы обернуть/расширить класс Stream, чтобы иметь такое поведение.

Если я пишу button.onClick.asBroadcastStream() снова в другом месте, указывает ли он на тот же поток, что и в основном?

Нет, по крайней мере, в текущей версии SDK. Поэтому, к сожалению, вам нужно где-то хранить ссылку на этот широковещательный поток и ссылаться на него, потому что многократное вызывание asBroadcastStream() не приведет к ожидаемому результату. (Примечание: по крайней мере, основываясь на быстрых тестах: http://d.pr/i/Ip0K, хотя documentation, кажется, указывает разные, мне нужно еще немного проверить, когда найду время).

Могу ли я сказать в одном из обработчиков, чтобы передать событие другому слушателю вещания?

Ну, есть в HTML земли, что означает, что событие не будет распространяться на другие элементы stopPropagation(), но это, вероятно, не то, что вы искали.

Для того, чтобы остановить запуск событий в других слушателях, необходимо, чтобы порядок слушателей вызывался. Я считаю, что порядок - это порядок регистрации этих слушателей.С точки зрения дизайна, я не думаю, что было бы неплохо позволить слушателю отменить/приостановить другие.

Распространение событий в HTML имеет смысл, так как речь идет об иерархии, но здесь у нас этого нет (и даже в случае событий в HTML для одного элемента может быть несколько слушателей).

Невозможно назначить вес слушателям или определить порядок важности, поэтому неудивительно, что нет способа остановить событие.

Вместо того чтобы позволить слушателям знать друг о друге и манипулировать друг другом, возможно, вам стоит попытаться подумать о другом способе подхода к вашей проблеме (что бы это ни было).

Это потребитель?

StreamConsumer - это класс, который можно реализовать, если вы хотите разрешить передачу других потоков в ваш класс.

+0

Вы ошибаетесь в отношении 'asBroadcastStream()' –

+0

Хмм, я могу ошибаться, этот код: http://d.pr/i/Ip0K однако печатает сначала 'false', а затем' true'. Поэтому они ссылаются на разные объекты. Я могу рассказать об этом более подробно, когда найду время. Могут также быть изменения в кодовой базе, и помните, что то, что вы связали в своем ответе, отличается от, например, Реализация потока SDK :) –

+0

Ваш код создает два широковещательных потока. Если вы вместо этого вызываете asBroadcastStream() в первом потоке вещания, который вы создали, вы получите то же самое. Это то, что задают. Реализация потока возвращает это, если это широковещательный поток. Я ссылался на поток, используемый в вопросе. –

1

Могу ли я узнать, что в потоке есть два слушателя?

Нет, у вас есть «поток», который обертывает обработку событий DOM. Таких функциональных возможностей нет.

Могу ли я приостановить или отменить всех других подписчиков?

Посмотрите на Event.stopPropagation() и Event.stopImmediatePropagation(), и, возможно, Event.preventDefault().

Если я пишу button.onClick.asBroadcastStream() снова в другом месте, указывает ли он на тот же поток, что и в основном?

[Обновлено] Нет, current implementation не дает такой же поток обратно, так как onClick геттер возвращает новый поток каждый раз, когда она вызывается. Однако возвращенный поток уже является широковещательным потоком, поэтому вы не должны вызывать на нем asBroadcastStream(). Если вы это сделаете, вы будете просто получать ссылку на тот же объект назад.

Stream<T> asBroadcastStream() => this; 

Могу ли я сказать, в одном из обработчиков не миновать событие на другой вещательном слушатель? Это потребитель?

Опять же, посмотрите на Event.stopPropagation() и Event.stopImmediatePropagation(), и, возможно, Event.preventDefault().

+0

'Event.stopPropagation()' ** не будет ** предотвращать вызов других слушателей (http://d.pr/i/4ZFx - печатает дважды). Это просто прекращает распространение, что также является чисто DOM-вещью из-за иерархии. Помните, что потоки используются для многих целей, а не только для DOM. :) –

+0

Вы правы, для чего предназначена немедленная версия, но вы останавливаете только обратные вызовы и не гарантируете порядок ... Конечно, потоки используются для многих вещей, но вопрос о DOM. –

+0

Я также должен добавить, что вам не нужно вызывать asBroadcastStream() для DOM-обработчика, поскольку он уже является широковещательным потоком. –