In AngularJS 1.5 we can use attribute binding to allow easy use of input-only, output-only and two-way attributes for a directive or component. Instead of manually parsing, watching and modifying attribute values through code, we can simply specify an attribute binding by adding a property to the object hash of:

angular.module('..').directive('myDirective', function() {
    return {
        scope: { myAttr: '<' }, // input-only attribute binding
        // ...
    }
});

In this blog post we will learn how attribute bindings differ between AngularJS 1.5 and Angular 2 and what we can learn from Angular 2 to make your HTML and JavaScript in Angular 1.5 more descriptive.

Attribute bindings in Angular 2 versus AngularJS 1.5

Angular 2 only offers two (unique) types of attribute bindings, the input and output binding. By contrast, AngularJS 1.5 offers 4 different types of attribute bindings:

  • the @ type: binds to the value of DOM attribute and therefore is always of type string; the value can be made dynamic by placing expressions inside { { .. }}.
  • the < type (as of AngularJS 1.5): an input-only binding on the evaluated result of an expression specified in the value of the DOM attribute that is evaluated in the context of the parent scope.
  • the & type: an output-only binding resulting in a function that when invoked executes the expression specified in the value of DOM attribute in the context of the parent scope.
  • the = type: an input-output (two-way) binding that can be considered a combination of < and &; Hence Angular 2 actually offers input- and output bindings but allows combining the both to create two-way bindings.

Although Angular 2 only offers 2 types of attribute bindings it still offers two-way binding for its ngModel directive and actually combines both the @ and < in its input attribute binding support.

The issues of the AngularJS 1.5 attribute bindings

One of the things that always bothered me while using AngularJS 1.5 is that you can't clearly see the type of binding you are using from looking at the HTML code. To make things worse AngularJS 1.5 offers 2 different styles to provide input values:

  • Using the (preferable) input-only binding < or alternatively the two-way binding =, we can specify an expression in the value of the DOM attribute
  • Whereas using the @ binding, we can bind a string value of a DOM attribute that can optionally be made dynamic by using { { .. }}

How Angular 2 differentiates between all 4 types in HTML

The great thing about Angular 2 is that you actually can see from the HTML which style is being used:

  • When square brackets are placed around the attribute name then an expression is used:

    Highlight me!

  • And when using no brackets the string value of the DOM attribute will be used:

    Highlight me!

    Or alternatively use { { .. }} to make things dynamic:

    Highlight me!

Additionally Angular 2 allows you to specify a:

  • output-only binding by using regular (non-square) brackets around your attribute name:

    Yellow

  • two-way binding by using both square and non-square brackets (mnemonic aid: "banana in a box") around your attribute name:

NOTE: Angular 2 uses case-sensitive (camel-cased) attribute names (allowing 1 to 1 mapping on JavaScript object properties) whereas AngularJS 1.5 uses dash separated attribute names in HTML that are normalized to (lower) camel-cased property names in JavaScript. Once you get the hang of the new Angular 2 template syntax you hopefully agree with me that the Angular 2 syntax is a lot more descriptive.

Alternative canonical syntax in Angular 2

Instead of using the (odd looking) brackets around the attribute names we could also use so-called canonical syntax:

  • Instead of square brackets we you prefix the attribute name with 'bind-':

    Highlight me!

  • And as a alternative for regular (non-square) brackets we could prefix the attribute name with 'on-':

    Yellow

  • And instead of using both type of brackets at once we could also prefix the attribute name with 'bindon-':

How we could use the canonical syntax in AngularJS 1.5

To make our HTML templates in AngularJS 1.5 more descriptive we could use the canonical syntax of Angular 2 as a convention while writing directives:

  • a < binding should be prefixed with bind in its normalized attribute name:

    scope: {myHighlight: '

  • a @ binding should not be prefixed

  • a & binding should be prefixed with on in its normalized attribute name:

    scope: {click: '&onClick'}

  • a = binding should be prefixed with (the somewhat ugly) bindon prefix in its normalized attribute name; or alternatively (which should be preferred) you could decide not use the = binding at all.

How the HTML of your Angular 1.5 application would benefit

By applying the canonical syntax convention while writing your directive (or component), your HTML will be much clearer:

  • whether an input-only < ('bind-' prefix) or @ (no prefix) was used should now be really clear.
  • an output-only & binding is also very easily distinguished due to its 'on-' prefix
  • you (hopefully) will find that the 'bindon-' prefix (for a = binding) is really awkward ... ... and hopefully choose the input-only < binding instead.

Although you can only use the convention for AngularJS 1.5 directives and components that you develop yourself, using the canonical syntax notation would still be a great benefit and also will help you in a future migration in Angular 2.

shadow-left