Talkin' 'Bout Angular Directives
In this post, let’s take a look at the power of directives, and in particular, the power of isolate scope-based directives.
In the beginning
Let’s start with this use case: I’ve got a list of friends and I want to list out their name and their hobby. The html looks like this:
1 2 3 4 5 |
|
…And here’s the controller:
1 2 3 4 5 6 7 |
|
Pretty straightforward. Well, let’s add to the use case: I want to be able to “cool-i-fy” any friend in the list by clicking them—no matter who I click, I want their name to be upgraded to “B.B. King” and their hobby upgraded to “guitar”. Instant coolness!
So, I do something like this:
1 2 |
|
…and the corresponding method in the controller:
1 2 3 4 |
|
Still straightforward, and works well.
Enter: A custom directive
But wait, I want this to be available throughout my app, anywhere I’ve got a list of friends. And I show a list of friends 24 different places. Sounds like a job for a reusable custom directive!
So, I’m going to create a directive, coolnessDir, that can be reused anywhere. Here’s what the html looks like:
1 2 3 4 5 |
|
Nice, neat, compact html, which is what angular directives are awesome for. Here’s our directive:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
I rip the coolifyMe
function out of the controller altogether. Notice that the coolifyMe
method in the directive’s link
function (I have a link
function because we’re manipulating
the DOM) looks nearly identical to our old method.
Okay, everything’s good. Works like a champ.
A problem arises
But wait. There is a list where I want to use this directive, but it’s controller defines the list as follows:
1 2 3 4 |
|
What’s this enemies
business? My directive code template refers to friends
in
its template—this will break!
Isolate scope to the rescue!
Isolate scope comes to the rescue here—it allows us to seal off the directive from
the enclosing scope(s), and “poke holes” selectively to allow certain values through,
while also allowing us to redefine those values. We’re going to make sure that whatever
value gets through to our directive’s template, it’s called friend
!
First, here’s what our html looks like:
1 2 3 4 5 |
|
Notice that we added an attribute to our directive: friends
. This is the hole
through to the directive. Speaking of which, here’s the code now:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Notice how we have a scope property now, and we define a key friends
, which matches
our attribute name that we added. The equals sign says “we want to two-way data
bind this, and furthermore, do it as the same name: friends
“.
Now, we can easily use this directive wherever—-all we need to do is change the
attribute friends=
to be whatever the controller sets the value of the list to.
This insulates our usage of friends
in our directive from breaking.