Better way to trigger events with Backbone/Marionette? - backbone.js

What's the difference between trigger and triggerHandler?
Does it differ from triggering events for elements using for example jQuery?

First, let's put jQuery apart, cause it triggers events with its internal mechanisms.
They bubble if triggered on elements, and surely don't when on objects, but they trigger only jQuery handlers.
And for Marionette, the preferred way is to use triggerHandler, because it not only triggers handlers, but also calls onMethod events.
See docs like https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.functions.md#marionettetriggermethod to learn more about that.

Related

Backbone listening to collection sync event in my View [duplicate]

What are the advantages and disadvantages of the following 2 lines of code? I don't understand why there are 2 different ways to do the same thing.
this.listenTo(app.Todos, 'change:completed', this.filterOne);
app.Todos.on('change:completed', this.filterOne);
Also when using .on, how do I determine is the default context?
listenTo is the newer and better option because these listeners will be automatically removed for you during stopListening which is called when a view gets removed (via remove()). Prior to listenTo there was a really insidious problem with phantom views hanging around forever (leaking memory and causing misbehavior) because view methods were referenced as event listeners on models even though the view instances themselves were long gone and no longer in the DOM.
If you want to read the back story for listenTo, search the backbone github repository for listenTo and read through some of the longer issue discussions.
As to the default context, several things can end up bound to this:
if you do the binding via this.listenTo, it will always be the view instance (pointed out by Wim Leers in the comments)
without this.listenTo, the story gets complicated
For misc events, it will be the global object (best to avoid this)
for DOM events, it will be the source element just like in regular DOM event binding
If you provide an explicit context (the 3rd argument to foo.on), backbone will use that (thus this is a more robust approach)
If you use the ECMA standard function () {//your event handler}.bind(this), you can also manually control the context (also recommended)
As #mu pointed out, _.bind or $.proxy are available alternatives to ECMA function.bind
For backbone views, doing this.bindAll('onClick', ...) will ensure the view instance is the this context when any view methods are used as event handlers
any events wired up by using the view's standard events property will get bound for you automatically to the view instance by backbone (this is belt & suspenders with bindAll)
So to summarize into some guidelines:
use the events property whenever possible as it is concise and correct
use this.listenTo for all bindings to models and collections
any additional bindings remember to bind the context reliably using your preferred method. I usually use ECMA Function.bind because hey, standards, but there are several good options here.
With listenTo, the object whose events you want to listen to is passed as the first argument. In the case of on, it is actually a method on that object.
The advantages of listenTo over on are:
The listener keeps track of all the event handlers, making it easier to remove them all at once when needed.
The callback’s context is always set to the listener itself.

How do I subscribe to React's global virtual events?

Is there a standard or hacky way I can listen to all events for a given React application tree's events? E.g. all onClicks.
edit: No really, I want all events, not just specific ones.
AFAIK there's no standard way to do this. To be precise you probably just want to listen for dispatches to synthetic event handlers, rather than listening to all events. For example just moving a mouse across the screen generates a stream of mousemove events.
To capture the event dispatches you would probably need to manually hack a listener into executeDispatch in https://github.com/facebook/react/blob/v0.14.6/src/renderers/shared/event/EventPluginUtils.js
I'm hoping the your application for this is just for debugging legacy spaghetti code. Incorporating any kind of global listeners into production code would be asking for trouble.
You could just listen to events for the outermost container. That would include all the children. Then you would get the element under the location of the event.
Something like;
let x = event.touches[lastTouch].pageX;
let y = event.touches[lastTouch].pageY;
let element = document.elementFromPoint(x, y);

What changed in event handling with Backbone.Marionette 1.0.0-beta1?

I just tried the new Marionette 1.0.0-beta with my existing project. After fiddling around with it for many hours, I must say the altered event handling confuses me.
Events seem to fire doubled. May be an artifact of the new triggerMethod() call?
Event bubbling in CollectionViews doesn't seem to work for standard events like 'item:rendered'. Those fire inside the ItemViews, but not the parent CollectionView. Is this intended?
What are the different event handling methods are meant to be used for? EventAggregator, EventBinder, Wreqr, native Backbone Events, …?
Would be great, if you could clear things up. It would also be great, if you could mark the existing documentation as being appropriate for what versions of Marionette.
Regarding the event bubbling in CollectionViews, there is a pull request to fix this as it is a bug

Direct Routed Event question

A colleague and I were chatting about routed events, and we came up with some things that didn't make a lot of sense. Primarily, what is the purpose of a Direct event, and why are both LeftMouseButtonDown and PreviewLeftMouseButtonDown direct events as opposed to bubbling and tunneling respectively?
According to the documentation, the LeftMouseButtonDown (and preview) events appear to behave as bubbling and tunneling events, except that the event is raised and reraised as these events traverse the tree. Since direct events can only be handled by the source of the event, it follows that any UIElement could handle a direct event since each one is raising the event and is also therefore the source. (Unless reraising the event is different than raising?). Why are these then not tunneling and bubbling like so many other similar events?
Neither my colleague nor I could come up with a use case in which we would ever create a custom event using a direct strategy (although we came up with some for tunneling and bubbling), yet LeftMouseButtonDown, one of the most common events (if not THE most common) is using this strategy.
Anyone have any ideas about the rational behind this?
Thanks!
My guess would be performance and there are considerations for having multiple events for the same thing.
There is already an event for MouseDown, to route both that and LeftMouseDown wouldn't make much sense. Finally, which would fire first and would cancelling\handling the first prevent the other? It sounds like it would be too easy to handle the same event twice.

Difference between OnLoad method and Load event?

What is the difference between OnLoad method and Load event? I am developing WinForm controls.
Should I register to Load event or override the OnLoad method? What are the advantages and the disadvantages of each one?
I'd go for overriding OnLoad, so you spare the CPU cycles to invoke the event handler.
The general pattern is to override a method, if you inherit from a control; otherwise, subscribe to the event.
But remember to call the base class' OnLoad method, because that's where the Load event invoked.
OnLoad method is the one that raises Load event. It's a standard pattern in framework classes, and a generally recommended one - for any event Foo, you have a virtual protected method OnFoo which raises that event; and no other method of the class raises the event directly, but always calls OnFoo.
If you need to handle the event on this, it's usually both easier and faster to override OnFoo.
OnLoad is the default event handler used in VB.NET to handle the Load event. I typically override this method when I need to attach code to the load event. There are also default functions for the other Page Life Cycle events: OnPreRender, OnInit, etc.
Just to add a bit of clarity to the existing answers, an event handler is something that 'waits' for the event to trigger. This requires some CPU overhead as you need to have a thread 'listening' for the event to occur. This would be something like MainWindow_Load() in a winforms application. However, since we already know 'when' the event will happen (it happens as soon as the form loads), there's no reason to actually use an event handler. It's not like a click event where we have no clue when the user might click in which case you really do need an event handler. So instead of holding up some CPU processing, we can create a method in the class which simply forces the Load event to occur which is called invoking the Load event.
This is why it's preferable to use the OnLoad method when possible, in situations where you always know when the event is going to happen.

Resources