Sharing Top Content from the Angular-sphere.

Event Aggregator in angular application

Event Aggregator in #angular #application 
#angularjs #apps #app #frontend

  • The scope.$broadcast sends events down through the scope tree.
  • Passing too many events through root scope degrades the performance and potentially has a side effect on the other micro apps.
  • Using $broadcast on root scope is also not the best idea (performance-wise) as events will go down to all child scopes.
  • Micro apps are well separated and, last but not least, I don’t have to remember to deregister an event handler bound to root Scope – it happens automatically when the scope of a subscriber is destroyed.
  • Each micro application is an angular application which can exist on its own independently.

The concept is very simple. The Aggregator gathers events from multiple sources into a single object to simplify relations between event publisher and subscriber. The pattern is very similar to the Observer however, there is a difference worth mentioning. The Event Aggregator sits in the middle between objects, emitting events (publishers) and subscribers (objects wishing to receive events). The Observer is a pattern where the subject holds a list of observers and notifies them on state changes.

@NeotericEU: Event Aggregator in #angular #application
#angularjs #apps #app #frontend

The concept is very simple. The Aggregator gathers events from multiple sources into a single object to simplify relations between event publisher and subscriber. The pattern is very similar to the Observer however, there is a difference worth mentioning. The Event Aggregator sits in the middle between objects, emitting events (publishers) and subscribers (objects wishing to receive events). The Observer is a pattern where the subject holds a list of observers and notifies them on state changes.

You may wonder why do I write about these patterns. Let me give you a little bit of a background.

At Neoteric, we adopted a Micro Application approach for our frontend applications architecture. Each micro application is an angular application which can exist on its own independently. The Micro App does not depend on any other micro application. These apps are built from angular modules which we try to keep loosely coupled. All micro apps depend on the Application Core which defines the third party dependencies and provides a common set of widgets and services.

That architecture scales very well and promotes code reusability. We have already built a suite of apps. As of now, a NeoB2B suite consist of the following apps: tasks, docs, workflow, and contractors. Each of them is a separate application and we can combine them in any way we want.

The architecture that we developed is interesting on its own, but this is way beyond this blog post. I will probably come back to that at a later time, if you will be interested.

This short introduction should be enough to understand the problem that we had to solve and the motivation to introduce an Event Aggregator to Application Core.

Micro applications depend on the Core and can communicate with the Core. However, we need a way to enable that communication without creating too tight a relationship between the Core and the micro app. In angular there are a few notifications mechanisms, including scope emits or broadcasts and registering watches on data models.

The scope.$broadcast sends events down through the scope tree. The $emit sends events up through the scope tree.

In most cases $broadcast makes less sense, as only the components below the event publisher in the scope tree will be notified. Using $broadcast on root scope is also not the best idea (performance-wise) as events will go down to all child scopes. In both cases, usually, this is not what you want.

On the other hand, parent-to-child communication can be easily achieved in a different way – for instance:

The child-to-parent communication can be easily done by using a special & binding and passing a callback function or by injecting a parent’s controller instance to child directive with the help of required attribute.

Do we need events?

In general, events should be avoided. It is more difficult to follow and understand the execution of an event driven application than of regular synchronous functions calls. If you are going to use events, make sure you need them. In most cases events can be avoided (see the section above). As in angular two-way data binding solves majority of data synchronisation problems, overusing events is a symptom of a problem with the data model.

So when should we use events?

Events work best when you need to pass the information to components that are not directly related or when you simply do not know in advance which components should receive this information. One good example of global application event is changing the language. There are many components potentially interested in consuming this event and the language switch widget is not related with them at all.

For these type of issues in angular apps, we can leverage the root scope which naturally plays an Event Aggregator role. The scope object has all the necessary methods and root scope is available globally. So far so good. However, there are a few problems with this approach, which we should at least be aware of:

Recently I have come up with a simple idea inspired by the Backbone/Marionette to implement an Event Aggregator factory and create as many aggregators as needed. The implementation is pretty straightforward. I decided to decorate the scope object, precisely its two methods: $on and $broadcast. Why $broadcast? Because, the scope object created by $rootScope.$new has a parent rootScope and I don’t want my events to interfere with rootScope.

Here is an implementation of basic Event Aggregator

In practice, I would need a single global Event Aggregator which will be available for all micro apps and will facilitate communication between Core and Micro apps (as well as app to app if needed). Additionally one or more aggregators for micro apps. I can easily achieve that by creating a service which is an instance of Event Aggregator, take a look:

This approach has several benefits. I am not polluting roots scope anymore. Micro apps are well separated and, last but not least, I don’t have to remember to deregister an event handler bound to root Scope – it happens automatically when the scope of a subscriber is destroyed.

Event Aggregator in angular application

Comments are closed, but trackbacks and pingbacks are open.