Backbone.js catch events by RegEx? - backbone.js

I was looking around but could not find anything whether it's possible to add event listener by RegEx rule?
I.e.:
EventBus.trigger('catalog:filter');
EventBus.trigger('catalog:removed');
And I want to catch them in two different ways:
1) By binding directly on event i.e.:
EventBus.on('catalog:filter', callback);
2) By binding for RegEx test and catching all events of that type i.e.:
EventBus.on(/catalog/, callback);
The second one should catch and handle both events 'catalog:filter' and 'catalog:removed'. This is in a way the same as model "change" and "change:[attribute]" way to bind events. It doesn't nesseceraly have to be RegEx object to work.
Thank you

Both of your problems can be solved by namespacing backbone events. I use it in a major project as app wide event bus and it is doing marvels. You can find one of implementations in here Backbone.namespaced-events and here is Dereck Bailey post about dos/donts of event agregation Revisiting The Backbone Event Aggregator: Lessons Learned

Related

What's the additional benefit of Event Aggregator in Backbone Marionette compared to the built in Backbone Events?

I have recently looked at Backbone.Marionette.
It mentions the Event Aggregator in a way that seems to be something new.
https://github.com/toekneestuck/edgefonts-preview/blob/master/components/backbone.marionette/docs/marionette.eventaggregator.md
However I don't really see the added benefit to normal events. Doesn't following Code provide you the same?
var dispatcher = _.clone(Backbone.Events)
These are almost exactly the same things. (check the code)
The difference is that EventAggregators is a "class" which can be instantiated (wherea Backbone.Events act more as a mixin).
Being a "class", EventAggregators can be extended.
EventAggregators.extend({ /* your new methods */ });
The difference is really small, but goes a long way in reducing boilerplate necessary to create a event hub with custom prototype methods - and extending them in sub-eventAggregator.

Difference between backbone on/off (teardown) and listenTo/stopListening Implementation

I am currently using backbone to implement my app. As part of memory management, I will trigger a teardown of all the views when I am switching views
teardown: ->
for viewName, view of #subViews
view.teardown()
for object, events of #objectEvents
#_handleObjectEvents("off", object, events)
#off()
#remove()
#undelegateEvents()
#
Is this approach sufficient to ensure that most of the memory issues are resolved? The challenge I see here is that I need to track all the subviews of each view and call teardown for all main views and subviews as part of the cleanup.
I did some searching and found that backbone also has these two events: 'listenTo' and 'stopListening' where we control the binding of events to models at the view level.
view.listenTo(model, 'change', view.render);
view.stopListening(model);
My questions is, is there an overlap between my teardown implementation and using 'stopListening'? Can I just solely use 'stopListening' for memory management?
The short answer is yes, there is an overlap.
The more complicated answer is listenTo/stopListening methods introduced in Backbone 0.9.9 already use on/off methods but with some useful addition – they store current event listeners in internal object called _listeners.
The benefit of using this object is that you always know full list of all your listeners – you can iterate over it and remove specific elements from it (remember that a listener is just a function and a function is just an object).
So, you can call it this way:
this.stopListening(emitting_object, ["reset", "add"]) // Removes listeners for "reset" and "add" on emitting_object
this.stopListening(emitting_object) // Removes all listeners on emitting_object
this.stopListening() // Iterates over _listeners object and removes all listeners (probably the most usable case)
So, using this method, you can convert your teardown method to something like this:
this.teardown = function(){
this.stopListening();
...
}
I'd recommend using listenTo method. The niceness of it is that when you use the remove method on your view, it will automatically unbind (call stopListening) on what it's listening to. According to Derrick Bailey, it also unbinds the events under the events property.
What I will do, since I am in the process of upgrading my app to 0.9.9 from 0.9.2 (which actually still works so far), is just switch around all of my ons/offs to listenTo and stopListening. I also, mostly, have close methods on there. I will, however, still call undelegateEvents, just in case. Doesn't hurt to know that you're still getting rid of the event listening.

Backbone.Marionette and Event Aggregator

Referring URL : http://davidsulc.com/blog/2012/04/22/a-simple-backbone-marionette-tutorial-part-2/
I am naive into backbone and event Aggregator. Can you please let me know the reason to use the following line of code.
this.model.addVote();
MyApp.vent.trigger("rank:down", this.model);
it seems some other possibility could be
this.model.addVote();
this.model(rankDown);
or the other way
MyApp.vent.trigger("addVote", this.model
Kindly explain thanks.
Running Sample: http://jsfiddle.net/Irfanmunir/966pG/29/
Events in general are useful for decoupling objects from each other, while still allowing them to communicate. The event aggregator pattern (or pub/sub pattern) at an application level allows further decoupling by having a 3rd party in the mix: publisher, aggregator, subscriber. This way, neither the publisher nor subscriber have to know about each other. They each know about the event aggregator only.
I wrote up a small article on this a while back:
http://lostechies.com/derickbailey/2012/04/03/revisiting-the-backbone-event-aggregator-lessons-learned/
In this case, the events are used because the model needs to be manipulated in the context of the collection that it belongs to. Rather than going through the model to get to the collection (which it might not be directly assigned to... models are not required to be part of a collection), it's easier and more flexible to raise this event and have it handled somewhere more appropriate.

Backbone.js - View in Collection adding item to another (sibling) Collection

In my example I have a parent model (ModelParent) with two collections (A and B), which hold ModelA's and ModelB's respectively. There are associated views for each model (ViewParent, ViewA, and ViewB)
I would like a function in ViewA to add a new item to CollectionB.
What's the best way to do this? (couple of possibilities below):
Should ViewA be passed a reference to ViewParent, when it is created? How best to do this? (as far as I know there is now in build parent reference)
Should ViewParent be stored in the window scope, so that ViewA can refrence it like window.ViewA? (This seems wrong to me)
Another alternative than listening directly to events from your collection, is the use of an eventBus. Derick Bailey from Los techies wrote a nice article where he introduces the idea of communication between different components (in his case views) via an eventBus.
If you are firm with coffeescript - and possibly even if you're not - you should also check this nice extension from Adam Thurlow.
Side note: If your situation simply requires communication between the two elements an eventBus is most likely overkill, although the idea is imho ultra simple. Apart from that, I am of the believe, that a central component for communication is worth the effort as it simplifies messaging, supports decoupling and gives your architecture a reliable consistency.
I would consider thinking about it a different way. I believe it would be cleaner if you didn't have to pass references all around your views. Instead, use backbone's built in event model and keep the "add new item to CollectionB" logic inside ViewParent. When ViewParent instantiates ViewA, you could immediately bind to an event on it:
this.viewA = new ViewA({});
this.viewA.bind("some_event_that_requires_adding_to_collection", this.onViewAEvent);
Inside ViewA, whenever you want to add to CollectionB, just trigger the event:
this.trigger("some_event_that_requires_adding_to_collection", itemIWantToAdd);
Add additional arguments to the trigger call to pass them to any callback bound to the event.

event or Action<> on method complete?

Presuming you have an email folder and messages in it. Each message has Body property, which needs to be loaded async and notify you when done, how would you approach this?
1 - Message.LoadBody() + event Message.BodyLoadComplete
2 - Message.LoadBody(Action completeDelegate)
For the sake of completeness WPF and Prism are involved.
Thanks!
Edit:
Message will be a UI entity which will wrap a IMessage interface (that is not UI Ready (no INPC)), so the reason i'm asking is that we have to settle for an interface between UI and business layer.. IMessage. (The Business layer will be using an Imap library that already has some async pattern, but we don't want to depend too much on any imp, thats why i'm trying to figure out the best interface ..
If you're using .NET 4, I'd use:
Task<string> LoadBodyAsync()
(You might want to implement this using TaskCompletionSource<TResult>.)
The caller can then add continuations etc however they wish... and most importantly, in the brave new world of .NET 4.5 and C# 5, this will work seamlessly with the async/await features.
Of your two options:
Message.LoadBody() // Plus an event, Message.BodyLoadComplete
// or ...
Message.LoadBody(Action completeDelegate)
The event option is more flexible and may sometimes be less painful to use. If you don't care when or if LoadBody completes, then you aren't forced to provide a fake callback. And you can bind the completion event to multiple event handlers, which might sometimes be useful (e.g. if multiple UI controls need to be updated).
Both your solutions are non-typical, though. The typical "old" way to do this is for LoadBody to be split into BeginLoadBody and EndLoadBody, and give the user an IAsyncResult. See this article. The typical "new" way to do it is outlined in Jon Skeet's answer.
If you're using Prism you should consider using the EventAggregator and publishing a message to indicate a mail has loaded. This will allow you to easily have multiple loosely-coupled subscribers for this "event".
Using the EventAggregator is an elegant solution for publishing events, and leads to a much cleaner and decoupled architecture which is easier to extend. For instance, if you wish to add a new feature to email loading such as progress indication, you can simply subscribe to the EmailLoaded message and you're done, you don't have to tightly couple your new component to emails via an event or callback, they do not need to know about each other.

Resources