I just started using Bacon.js and it's truly awesome. Although sometimes I do struggle to find the right way of doing things. For example I want to have an angular directive with a draggable part. I shamelessly pick into someone's jsBin and tried to adapt that code for angular
I am trying to make a table with resizable columns. So if I do something like this in column-header directive
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"
This kinda works, but now this directive will register 'mousemove' and 'mouseup' events all over the page. I probably can add some takeWhile
statements, and the matter of fact I just tried and it didn't really work.
I mean what's the pattern of using global event handler's like $(document).asEventStream('click')
in angular app?
You can create handlers in a directive and then use
takeWhile, takeUntil
but then that will work only once, since the stream eventually stops. Do you have to re-initialize the stream every time you need to respond to adocument.click
? Also isn't it a bad thing to have "document" level events in bunch of places? If you write in a directive$(document).asEventStream('mouseup')
and use that directive two hundred times, wouldn't that create actual two hundred listeners?Or you gotta introduce these sort of stream variables globally for entire app to use, and then inside a directive do
map
,filter
andreduce
? But then what if someone callstakeUntil
and stream stops flowing completely and can't be used in other parts of the app?Or maybe listen on the top level of the app and emit $rootScope event for every value in the stream and then in a directive or view use ng-bacon's
$rootScope.$asEventStream(event)
? Wouldn't that make the app somewhat less responsive? Say if you need to respond on 'keydown' and 'keyup' events?
Can someone show me an example how FRP can be used in angular directives (particularly drag-N-drop sample would be appreciated)