In the DDAU pattern, data flows one-way and there are no two-way bindings. Different parts of your application can remain highly decoupled and predictable, which means you will always know the source of an object’s change. If you’ve read my post on functional programming and the observer effect, you’ll understand why it’s important to keep your components free from side effects.

Instead of spending time cobbling together your own makeshift framework with a dozen micro-libraries and bike-shedding on the best way to implement a feature, using Ember means instant productivity and quick developer on-boarding. Combined with the DDAU pattern and the Glimmer rendering engine, Ember developers have both productivity and performance out of the box.

Preparing your application for DDAU

When routable components land, controllers will be deprecated and removed. Controllers and views have always been confusing for new Ember users, and “80% of their use cases were to do something that was fundamentally a component” (watch Yehuda and Tom explain more in this video).

Since Ember components aren’t singletons, they will be torn down and re-rendered in an optimized fashion when Glimmer deems necessary. How then to handle state persistence when controllers go away?

For example, you might have some property on your controller that holds on to state that you would like to preserve throughout the app. To do so in Ember 2 (and today), we can remove that controller property in favor of “service-backed components”. The service will hold on to singleton component state, and explicitly injected only where necessary. Because services are powerful and can be easily abused, I’ll talk more about it at the end of this post.

Implementing service-backed components

In the following example, I’ll demonstrate how you can use services and one-way bindings today. You can follow along below as well as check out the demo.

Our little application consists of a couple of checkboxes for selecting animals. This selection needs to persist across different routes, and restore state when returning back to the route. All we need is to define a simple service that holds state for the selected items, and then inject it into the routable component.

In the route’s template, we can just render the injected service’s state using the each helper.

In our controller or routable component, we inject the service and define the action for handling the checked animal. The service’s bag of state is then passed into the component, keeping it as pure as possible. Although you could have just injected the service into the component, doing it this way makes things more explicit and allows the component to be decoupled from the service.

As mentioned, the service itself is simple. We can define more complex behavior later, but the underlying persistence for its state is just a JavaScript array.

Because our behavior is simple, we don’t need to define a sub-classed component in this example. The check action is passed in from the routable component / controller, so using closure actions in the component’s template means that we don’t have to cast sendActions into the void.

In our component’s template, we make use of small, composable helpers. These helpers are just simple JavaScript functions under the hood, and because they have return values, we can use them as Handlebars sub-expressions where we might have once defined a computed property.

The contains helper doesn’t ship with Ember, but the function itself is one line of code. There are a bunch of useful addons that add helpers such as these to your application — for example, ember-truth-helpers is an addon I find myself using in almost all my apps.

As mentioned in my previous post, the ember-one-way-input addon is an easy way to start using one-way bindings today.

I hope this simple example illustrates how you can build maintainable and performant apps with some of my favorite features of Ember — helpers, closure actions, components, and one-way bindings.

A word of caution about Services

As the cliché goes, “with great power…”. Because services in Ember are singletons, it becomes tempting to make multiple services and inject them everywhere.

If your main reason for creating a service is to use it as a global, that is generally a code smell because dependencies become implicit (we learned earlier that this is a bad thing) and parts of your application become tightly coupled. Instead, expose data and actions via interfaces to keep your code decoupled and explicit. Remember the Principle of Least Power, and only use a service when strictly necessary!

So when should I use a Service?

I like this Stack Overflow answer on when you should use a singleton. Essentially, you should only use one when you can only have a single instance throughout your application. For example, a shopping cart, flash messages, or activity feed could be great candidates for a service.

Thanks for reading! In my next post in this series, we’ll explore other advanced techniques for the DDAU pattern.

Until next time,

Lauren