kjo
kjo

Reputation: 35301

Confused by d3.js's event dispatch

AFAICT from the docs on d3.js events, all the parts of the code that generate or consume such an event must have access to the d3.dispatch() object on which that event were "declared" (for lack of a better word).

This means that this d3.dispatch object has to be globally visible, i.e. it has to be held in a global variable. Indeed, if the scope of this variable were any narrower, both generators and consumers of such an event would have to live within that same scope, and this clearly defeats the purpose of event-driven programming, which is to completely decouple the parts of the code (i.e., the scopes) where events are generated from those where those events are consumed.

The scheme's dependency on a shared dispatch object makes no sense to me. It would be a bit better (though, IMO, not ideal) if the value returned by d3.dispatch() were always the same object. AFAICT, the following test suggests that this is not the case (the leading > and < characters denote input and output, respectively):

> d3.dispatch() === d3.dispatch()
< false
> d3.dispatch( 'foo' )
< d3_dispatch {foo: function, on: function}
> d3.dispatch().foo()
VM10701:2 Uncaught TypeError: d3.dispatch(...).foo is not a function(anonymous function) @ VM10701:2InjectedScript._evaluateOn @ VM10514:883InjectedScript._evaluateAndWrap @ VM10514:816InjectedScript.evaluate @ VM10514:682

Have I misunderstood something?

Upvotes: 0

Views: 719

Answers (1)

Cool Blue
Cool Blue

Reputation: 6476

If you read the code you can see that d3.dispatch is a factory function that returns a new d3_dispatch object which is a function with new d3_dispatch_event objects added on it, which correspond to the arguments passed into the dispatch factory. The d3_dispatch_event factory returns an object with methods for adding and servicing and exposing listeners and their callbacks. It also forms closures on an associative array of listeners, which will be unique for each event.

So, basically, each dispatch is a new object with behaviour inherited from d3_dispatch.prototype and d3_dispatch_event.prototype and state closured in the d3_dispatch_event factory.

Upvotes: 2

Related Questions