Я только начал использовать Bacon.js, и это действительно потрясающе. Хотя иногда я изо всех сил пытаюсь найти правильный способ делать что-то. Например, я хочу иметь угловую директиву с перетаскиваемой частью. Я бесстыдно выбираю кому-то jsBin и пытался адаптировать этот код для угловогоFRP, угловые и глобальные обработчики событий
Я пытаюсь создать таблицу с изменяемыми размерами столбцами. Так что, если я что-то вроде этого в директиве колонного заголовка
link: (scope, element, attrs)->
el = element.find('.column-separator')
doc = $(document)
mMove = doc.asEventStream('mousemove')
startDrag = el.asEventStream('mousedown')
endDrag = doc.asEventStream('mouseup').takeWhile mMove
# in this case unlike the example in jsBin I don't care about vertical axis,
# only horizontal "X"
getDelta = (t)-> a = t[1]; b = t[0]; return a-b
add = (p1,p2)-> p1 + p2
draggingDeltas = startDrag.flatMap ->
return mMove
.map '.clientX'
.slidingWindow 2,2
.map getDelta
.takeUntil endDrag
pos = draggingDeltas.scan 0, add
pos.onValue (pos)-> el.css left: pos+"px"
Это своего рода работает, но теперь эта директива будет регистрировать «MouseMove» и «» MouseUp события по всей странице. Я, вероятно, могу добавить некоторые заявления , и дело в том, что я просто попытался, и на самом деле это не сработало.
Я имею в виду, что такое шаблон использования глобального обработчика событий, как $(document).asEventStream('click')
в угловом приложении?
Вы можете создать обработчик в директиве, а затем использовать
takeWhile, takeUntil
, но тогда это будет работать только один раз, так как поток в конце концов останавливается. Вам нужно повторно инициализировать поток каждый раз, когда вам нужно ответить наdocument.click
? Не так ли плохо, что события уровня «документа» в кучке мест? Если вы пишете в директиве$(document).asEventStream('mouseup')
и используете эту директиву двести раз, не создадут ли фактические двести слушателей?Или вам нужно ввести эти рода потоковые переменные глобально для всего приложения для использования, а затем внутри директивы сделать
map
,filter
иreduce
? Но тогда, если кто-то называетtakeUntil
, и поток полностью прекращается и не может использоваться в других частях приложения?Или, может быть, прослушать на верхнем уровне приложения и испустить событие $ rootScope для каждого значения в потоке, а затем в директиве или представлении использовать
$rootScope.$asEventStream(event)
? Не может ли это сделать приложение несколько менее отзывчивым? Скажите, нужно ли вам отвечать на события «keydown» и «keyup»?
Может кто-то показать мне пример того, как FRP может быть использовано в угловых директивах (в частности, перетащить-N-капельным образец будет оценена)
так вот проблема с использованием '' takeWhile' и takeUntil'. Позвольте мне описать это. Предположим, у меня есть директива, когда она зависает над ней, открывается div, а затем, когда пользователь щелкает куда угодно (document.click), он закрывает div. Обе операции управляются потоками 'toEventStream'.Я могу использовать 'takeUntil' для более позднего, но затем полностью останавливает поток, как мне перерегистрировать поток? Когда я пытался связать один «toEventStream» изнутри 'onValue' другого, это не сработало. – Agzam
также я где-то читал, что Бэкон все равно использует одинарные. Таким образом, регистрация событий уровня документа в кучке мест прекрасна. Все еще нужно использовать их с умом (с 'takeWhile' и' takeUntil') – Agzam
Один хороший способ отменить регистрацию - сохранить «близкий» поток. Этот поток получает значение, когда модуль/директива/любая часть кода закрывается/уничтожается. Вы добавляете 'takeUntil (close)' ко всем потокам, которые вы используете, в этом случае достаточно добавить его для запуска. – OlliM