In the previous section of this tutorial, we introduced ng-bind
as a way to connect controller models to the text content of HTML elements. There is an alternative, non-directive way of achieving this, namely double curly bracket notation or {{ }}
. To use it in index.html
we would edit the <div>
s as follows:
1 2 |
<div>{{title}}</div> <div>{{getTitle()}}</div> |
Typically {{ }}
is used over ng-bind
as it is less verbose (4 characters versus 10).
ng-bind
does have one distinct advantage, though. It prevents any temporary flashing of curly braces, which can happen if there is a gap between the browser rendering HTML and AngularJS executing. The ng-cloak directive is an alternative solution, but we won’t go into details in this tutorial.
Expressions
Both {{ }}
and ng-bind
require an AngularJS expression. AngularsJS expressions are similar in concept to JavaScript expressions but with subtle differences that I’ll highlight with examples.
We could change the expressions used in index.html
(currently title
and getTitle()
) to any of the following:
title + 1
– expressions can have operators. Here we are operating on a string, so 1 is converted to “1†(as per normal JavaScript) resulting in “Learn AngularJS1â€.title + ': ' + description
– expressions are forgiving.description
doesn’t exist, but the result is “Learn AngularJS: †rather than “Learn AngularJS: undefined†as you might expect.title + (description ? ': ' + description : '')
– conditionals are allowed but only in ternary form, so the result here is just “Learn AngularJSâ€.
Curly brackets are not allowed in AngularJS expressions, which means that blocks (e.g., if () { }
) and function declarations (e.g., function() { }
) are ruled out.
The recommendation is to have a model behavior instead of complex expressions. In general, it’s a good idea to keep your expressions looking attractive.
Two-way bindings
The connections made between controller models and HTML elements are more commonly known as ‘bindings’. All bindings in AngularJS are two-way. This means that any updates to bound model properties are automatically reflected in the HTML. Even at this early stage, our sample application has two-way bindings. It just doesn’t look like it because there is no binding that will update the model. Let’s change that now so that we can properly highlight two-way binding.
Edit index.html
as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<html ng-app="udemyAdmin"> <head> <title>tutsocean - admin area</title> </head> <body ng-controller="articleCtrl"> <div ng-bind="title"></div> <div>{{title}}</div> <input type="text" ng-model="title" /> <script src="angular.js"></script> <script src="app.js"></script> <script src="controllers.js"></script> </body> </html> |
In the above snippet, we’ve introduced an HTML text input element and attached an ng-model
directive to it. ng-model
listens for DOM events (e.g., keyup
) raised by the element, reads its value and writes it to the bound model property specified in the expression (i.e., title
). The text content of the <div>
s updates thanks to the binding created by ng-bind
and {{ }}
. Try this out and witness the magic of two-way binding.