codelord.net

Code, Angular, iOS and more by Aviv Ben-Yosef

Understanding Angular's @ Binding

| Comments

I’ve written about the new > one way binding in Angular, and explained the magic behind & bindings. It only felt natural to explain what is likely the least-understood binding type: @.

I’ve seen people use it by mistake, not understanding how exactly it works and when you should (or shouldn’t) use it. There are also situations where it makes things more explicit and clearer. Let’s dig in!

An example: a password input component

Say we want to create a very simple component that’s used to enter a password. It has all the needed validations, and we’d like to use it throughout our app, wherever the user needs to enter a password.

Our first pass might look something like this:

1
2
3
4
5
6
7
8
9
10
angular.module('app').component('passwordBox', {
  template: [
    '<input type=password ng-model="$ctrl.ngModel"',
       ' placeholder="{{ $ctrl.placeholder }}">'
  ].join(''),
  bindings: {
    ngModel: '=',
    placeholder: '='
  }
});

This simply creates a password input element and allows us to specify a placeholder if it’s empty.

Here’s how you’d use it in a template:

1
2
3
<password-box ng-model="$ctrl.password"
              placeholder="'Enter password'">
</password-box>

Pretty straightforward, but can you guess what’s bothering me?

The placeholder attribute will almost always be a simple string – why does every user of our component need to wrap it in quotes? Are we saying it would also be acceptable to pass a non string value, like an object? Surely not!

For exactly this purpose we have the @ binding – it allows us to specify that we want to receive the string value of the attribute.

Changing the bindings definition in our component so placeholder uses @ makes the password box component a bit slicker:

1
2
3
<password-box ng-model="$ctrl.password"
              placeholder="Enter password">
</password-box>

Angular will now plainly take the value of the DOM attribute (which is always a string) and pass it along to our component.

What if you need the string to be dynamic?

Just because we’re using @ binding doesn’t mean we will always have to stick with static strings. For example, we can make the placeholder dynamic:

1
2
3
<password-box ng-model="$ctrl.password"
    placeholder="{{ $ctrl.user }}'s password">
</password-box>

Angular will automatically interpolate that string whenever $ctrl.user changes, and that change will be reflected in our password box component!

This is a little gem in Angular that’s worth knowing: it allows us to write easier-to-use components, and provides explicitness. A win-win!

“Maintaining AngularJS feels like Cobol 🤷…”

You want to do AngularJS the right way.
Yet every blog post you see makes it look like your codebase is obsolete. Components? Lifecycle hooks? Controllers are dead?

It would be great to work on a modern codebase again, but who has weeks for a rewrite?
Well, you can get your app back in shape, without pushing back all your deadlines! Imagine, upgrading smoothly along your regular tasks, no longer deep in legacy.

Subscribe and get my free email course with steps for upgrading your AngularJS app to the latest 1.6 safely and without a rewrite.

Get the modernization email course!

Comments