MALE SPEAKER 1: So directives.
So what are directives?
I think directives are the coolest features of Angular
because what they basically let you do is teach the
Somebody on Twitter had an awesome quote, which I think–
I’m very proud of that they use this particular quote,
but, basically, they said, I’m pretty sure HTML6 goes under
the name of Angular.
And I think the reason why the person said that is because
Angular allows you to make new vocabulary for HTML so that
you can emulate just about any construct you can think of.
And the moment you get in the business of emulating
construct, which you really are in the business of is
Everybody knows what DSL is, right?
Domain Specific Language.
And so DSL for your application becomes–
HTML’s really good at one thing.
And that’s static documents.
But with the introduction of directives, you can extend the
And so now, whatever you think you wish you had in HTML, and
you don’t have it in there, well, now you can have it with
So directives is basically this magic.
And there’s also this magic that is
very unique to Angular.
No other framework has anything like this.
There’s other frameworks, for example, Knockout.
And I’m not an expert in Knockout, but they use the
same philosophy of using attributes of putting extra
behavior in side of the HTML and then
bind to those behaviors.
But it turns out that, in Knockout, the set of
vocabulary that they have is fixed.
If the authors of Knockout didn’t put it in there, you
But Angular’s very, very different in a sense that we
are the meta-framework.
We allow you to customize directives for yourself.
So let’s talk about what directives are because, well,
judging from the mailing list, and IRC questions, and so on,
I mean, there’s a lot of confusion about them.
And that’s probably my fault because I should’ve done a
better job documenting.
But at the same time, it is something that’s super
And we’re trying every day making it simpler.
But it’s just a complex piece of stuff.
So anyway, let’s dive into it.
So the first thing I want to show you is how Angular
actually bootstraps itself.
How does the whole thing kicks in?
So normally, right here, you put in ng-app.
We’re all familiar with this.
By the way, I love questions.
So as I’m talking, if you want to know anything, just come up
to the microphone and ask.
MALE SPEAKER 1: We have T-shirts for good questions,
and you don’t have to worry about de-railing me.
So normally, the ng-app.
And this is kind of a meta-directive that bootstraps
the whole application.
But in order for you to understand what’s actually
going on under the hood, I’ve created a manual
And the manual bootstrapping process is basically here.
And I’m going to go through it.
So as every application has to have, you have to wait for
You have to wait for the DOM to load.
Once the DOM is loaded, you can do a couple of things to
kind of get the application going.
So the first we have to do is, we have to find the root of
Normally, this is the location of ng-app, but in our case,
it’s just a root elements.
Then we have to list a set of modules.
Modules is probably another tech talk we’re going to have
to have, probably, on our next meetup and just discuss them.
Anyways, Angular has a built-in module called ng, and
that’s the thing that has all of the directives and
It turns out that the same APIs we used for building
Angular are the same APIs you get to use for building your
So there’s nothing special.
We don’t have any special access to the system, which is
important because it means that whatever we can do, you
So there’s this hidden module called ng, which you normally
don’t have to specify explicitly, but because we’re
doing a manual bootstrap, we have to do that.
So the next one is my application, and the my
application, that one simply says, make a new module called
my app, nothing really interesting there.
And the last one is an inline module and what this one does,
it basically tells the module system where the
The root element which we got, the holdoff says, this is the
root element, so from now on, this is what it is.
Anyways, it turns out everything in Angular is
And so this is no different.
So we create a root injector and we only create one
injector per application.
So if you’re ever in the business of creating a new
injector, you’re probably doing something wrong.
And from the injector, we get ahold of the compile service.
This is what does all of the magic.
And we’ll talk about this a lot more.
And what the compile service does is, it basically
traverses the DOM, starting at the root element.
And it looks for directives.
And we’ll talk more about how this is happening.
But once it discovers these directives, it executes its
And the compile function is responsible for returning the
Again, we’re going to talk about all this
stuff in more detail.
And it returns this thing called the composite linking
function, which is essentially a collection of all the
linking functions in the system.
And I know a lot of people, I’m sure have had questions
about what’s the difference in compiling linking functions?
So why do we call it a
compiling and linking function?
And basically, the reason is, we kind of borrowed it from
the idea of compiling in C. You have to compile your
objects and create objects file, then you have to link
And so something very similar is happening here, where the
first phase is, we’re simply looking for the directives.
And as we call them, it’s the compile phase.
And once we locate all the directives, we have the
linking phase, which actually attaches it to the scope.
So the next part is, we get a hold of the root scope.
Every application has exactly one root scope.
And then we call the composite linking function within the
And we kick the Angular to say, hey, go.
And this is basically a whole bootstrapping process.
So let me show you this inside of a debugger,
So I’m already, I’ve got myself to the injector.
And so now, if we look at the structure of HTML, sorry, let
me pull up the application over here on
the right hand side–
currently, this is the structure that the browser
loaded into the DOM.
This is basically one to one translation from HTML to the
There’s nothing has yet happened because we are
we haven’t done anything.
All we have done is kind of look for things.
And we have not even created the injector yet.
So we’re about to create injector.
So when we create injector, nothing really happens.
We get ahold of the compile service.
And now the magic is about to happen.
Now basically, we’re saying, compile service, go walk the
DOM starting at root element and go look for all those
And so, inside of our “Hello, world,” we have an li.
And it’s not cooperating again.
There is a strange bug inside–
So we are about to run the compile service.
So again, let’s go back to HTML.
And notice that we have basically the raw directives
as we have them in here.
So you guys are familiar with ng-model is a directive.
ng-bind is a directive. ng-repeat is a directive.
So now something interesting happens that, when we call the
compile function, we actually are going to execute the
compile function of individual directives.
Now, most directives have no compile functions.
So it’s going to no app.
But some do, for example, a repeater.
So pay close attention to what happens to the ui li node when
I step over the compile.
Let’s go back here and step over.
Notice, it has disappeared.
And if you look at the structure of the DOM, it has
been replaced instead with a little comment.
So what’s happening is that the Repeater says, well, I’m
going to have to make a whole bunch of copies of these
Because I’m a repeater, and so I need to be able to clone it.
And so its compile function simply yanks out the content,
puts it in a placeholder, which is just a comment, so it
knows where the other items are supposed to go.
And it, internally, then further compiles
the template itself.
And so the result is that at this stage we have transformed
the DOM structure because we extracted the
MALE SPEAKER 1: Yes.
I mean, if you remove a DOM element, it’s probably
considered a DOM fragment because it is no longer part
Yes, it’s basically been disconnected from the original
render tree, so, as you can see, the browser
So now comes the linking function.
And then a linking function is, every directive has a
linking function, I think.
And so, when we execute the linking function, and when you
step over it, notice, again, nothing happened to the DOM.
And that’s because linking function basically, it is, in
essense, it creates the view.
If HTML is your template, which then gets loaded and
becomes a DOM, then view is the live thing that knows how
to react to different events.
And so when the linking function runs, we create all
And again, when we write a directive, this is going make
a little more sense.
And so, at this point, we have a live view.
Except, as you can see, nothing’s being rendered on
And that’s because we have to kick the root scope and say,
And so the moment we run apply, wow, the whole thing
Does that make sense, in terms of bootstrapping process?
We’re going to delve more into these pieces more.
AUDIENCE: How do you avoid content flash [INAUDIBLE]?
MALE SPEAKER 1: How do avoid content flash?
We have a directive called ng-cloak.
You can check it out.
Basically, it’s a CSS rule that hides, basically, the
chunk of DOM until the compiling and linking function
And then compile function then puts it back in.
So that’s how we do that trick.
There’s other tricks you can do.
Talk to us maybe afterwards.
But it’s a good question, but it’s slightly off topic.
and we have a basic Hello World.
So let’s go to the next step.
So let’s build a directive.
So I created a very simple Hello World app.
And you can see the source code on the left hand side and
the actual app running over here.
And I’m assuming most of you guys are not Angular
beginners, so you can translate what’s going on.
But basically, when I type, you can see that
the name gets updated.
I have a single controller over here.
And the controller simply sets up a name and leak variables.
And then I simply have a piece of debug information to show
the name and debug down here.
And I have an input, which allows me to change the name,
and then there is our controller called Demo Greet.
So let’s write a directive Demo Greet.
So I’m sure you guys know how to register a directive.
Simply, you take the module for the application, and you
simply say directive, Demo Greet.
Now the interesting thing to notice over here is that we
use camel case in this location.
But when you’re actually invoking it from
HTML, it’s dash case.
It’s simply a precedence that jQuery and other people have
set, that in, HTML, because it’s case insensitive, you
have to separate the words by dashes.
But if you separate the words by dashes, then inside of
brackets and in quotes.
And so it’s a pain.
And to help you, basically, with that, we normalize it by
putting it into camel case for you, then
the access is simpler.
So the console over here simply–
we’ll print the console out over here and we’ll set the
text the Hello world.
So as you can see, inside of the div, this div, after the
application executives, simply has Hello world in there.
So let’s talk more about the compile and link function.
OK, so let’s make a compile function,
compile element, patterns.
And the job of the compile function is
return the link function.
And what I’m going to do is, I’m going to put a print out
over here, and I’m going to change this and say compile.
And it’s going to say compile function, and I’m going to
label this just for our benefit.
And let’s say I am going do element.addclass compiling.
And this is where the confusion begins, I think.
And let’s look at the DOM structure.
And so we see, the DOM structure has Hello World, and
it also has a class compiling.
So why in the world do we have two different ways of what
appears to be doing the same thing?
So before I do that, I’m going to do one more thing.
And I’m going to say, well, is the compile element the same
thing as the link element?
And when I run this, and I look at the console, notice it
says, true, over here, saying, the two of them are really the
So why do we have this?
Anybody want to take a guess why there’s
two different things?
OK, so this is where the confusion starts.
People say, where do I use a compile function?
When do I do a link function?
They are so similar, what’s the difference?
So hopefully we can explain this.
So the first difference you notice is the signature
between those two functions.
Compile functions doesn’t have access to scope.
And again, if you go back to the bootstrapping phase, you
we’ll see that this is when the compile function gets run.
The scope doesn’t have created until afterwards.
This is why we don’t have access to the scope.
But for many practical purposes, the two look the
same, until I do this.
And then the differences start to become obvious.
So notice the compile function got executed exactly once,
whereas the linking function gets executed once for each
iteration of the repeater.
So there’s two of them over here.
And once we have a repeater, the two are
no longer the same.
See, it says false.
So the compile element and the link element are
no longer the same.
You can also see, if I go here, that both of them have
the class compiling.
So now, how can it be?
How can it be that both have the class compiling when the
compile function gets executed exactly once?
And so the answer is that the compile function got to modify
the template, which ng-repeat used to stamp out new
So think of the compiler function as the thing that
works on a template and the thing that is allowed to
change the template itself by, for example, adding a class to
it or anything like that.
But it’s the linking function that actually does the work of
binding the two together because the linking function
has access to the scope.
And it’s the linking function that executives once for each
instantiation of the particular template.
So the only kind of things you can placed inside of the
compile functions are things that are common across all of
And that’s not very common thing to do because you might
place things like that adding class elements, but typically
the class elements you add are different for each instance,
so you can’t really put it inside of the compile phase.
Does that make sense?
I see a lot of confused faces.
AUDIENCE: [? Singleton ?]
MALE SPEAKER 1: I’m sorry?
AUDIENCE: It’s like a singleton?
MALE SPEAKER 1: Sure, you can think of it that way.
The point is, it’s the thing that runs on a template,
whereas the link function is the thing that runs on an
instance that’s actually instantiated.
And it’s confusing because, unless you’re inside of a
repeater, the two look identical because there’s a
one to one correspondence between the
template and instance.
But once you get into a repeater, that’s
no longer the case.
And so I’ve seen a lot of people write incorrect
directives because they put things that don’t belong
inside of the compile function,
they put it in there.
And it kind of works.
But then they put it inside of a repeater, and all hell
MALE SPEAKER 1: No, so typically, unless you’re
modifying the template, you should forget about the
compile function, just stick with the linking function.
Because the linking function is the thing that gives you
the proper instance and also the proper scope.
So the compile function is purely for modifying the
template and nothing else.
OK, I think we’ve made that point.
OK, so let’s do more fun stuff.
So this is kind of a made-up directive, it doesn’t really
So I’m just going to play with it.
But let’s get rid of the compile function because, as I
said, it’s very rare for you to having to use it.
So let’s make a link function.
And let’s try to do something useful.
So there’s a couple things you might want to do it inside of
You might want to be able to talk to the outside world, for
example, get ahold of a event from the user, for example,
like a click event.
You want to be able to read from the scope, and you also
would like to be able to write to the scope, maybe because of
So let’s say we would like to make it, so as I type over
here, this thing updates over here.
So you might be tempted to say, well, how about we just
say, Hello world, and we have a scope.
And the variable’s called name.
And so let’s just write something like this.
But if you execute this, it works the first time.
And then you start typing, and it no longer updates.
That’s because, at the beginning, the controller set
And so you were able to render yourself.
But then future updates, you simply are not being notified.
So this isn’t going to work.
What we need to do is we need to be able to
have a watch, basically.
So we have to say scope.watch.
What are we going to watch?
We’re going to watch the name property.
We’ve got to get the name out of this, and
let’s move this up.
And let’s put it like that.
And voila, we essentially have our own binding.
So keep in mind also that all the DOM manipulations should
really be happening inside the directive.
The point of the directive is to be the glue between your
DOM and your scope.
But if you think about it, it doesn’t really encapsulate the
system very well because what you really want to be able to
say– let’s get rid of the repeater for a second.
What you really want to be able to say is, configure the
directive with information.
So rather than hard wiring to name, you really want to say,
I’m telling you what to bind by passing the
name into the system.
And so we can set an attribute.
And when I set an attribute, we can get ahold of this
So instead of hard coding it to name, there is this object
And if we look at adders inside of our console, you see
that it shows all the parameters.
And one of the parameters is Demo Greet.
Now when this executed, Demo Greet was pointing to nothing.
So it shows nothing.
But because I updated it, let me refresh this, the Demo
Greet now points to name.
So instead of watching the name directly, I can simply
So watching the attribute on the element called Demo Greet.
And this will now perform the same operation–
essentially, the binding.
But it’s configurable.
I don’t have to watch the name.
I can watch other things than name.
And so this is a good way to parameterize your stuff.
Does that make sense so far?
I see a lot of confused faces and serious people.
I like people that are happy, not serious.
MALE SPEAKER 1: OK, so going right along.
So the other thing you probably want to do is, let’s
say we wanted to update the state of the parameters.
So what you could do is, you could say
scope name equals abc.
And it would work the first time.
But what if you wanted to make it abc every time
So we simply say, element, and this is kind of jQuery-like,
so you say bind click function.
And we say console.log click.
And we do something like this.
And now, every time I click, you can see
that the click’s working.
It’s coming up over here.
But nothing’s happening.
It doesn’t say abc.
It keeps saying world.
So what’s going on in here?
Well, what’s going on is that there’s really this Angular
world and non-Angular world.
And when an event comes in, when you’re inside of jQuery,
you really are in non-Angular world.
And the Angular just doesn’t know that
something has changed.
And so you have to tell Angular about it.
And there’s a lot of ways to tell Angular about it.
And so you might say, well, let me write something like
And that’s certainly one way to do it.
And so now, if I click on it, it changes.
I type, click, changes again.
But actually, it turns out this is not
[? an economical ?]
way to do this because what if name threw an exception?
So the better way to do is to say, function and
place it like this.
So now, when I start typing, and I click
on it, it gets reset.
And if an exception is thrown inside of this operation,
everything would work.
So the apply is basically the gateway that gets you from
outside of the Angular world into the Angular world.
OK, but, again, there’s a problem here which is that
we’re hard coding it to name.
It would much rather have it as a parameter that’s being
And so there’s a service call parse.
And so I can ask for the parse service
because this is Angular.
You can just ask for things.
So you say, I want a parse service.
And what the parse service allows you to
do is to say, parse–
what are we going to parse?
We’re going to parse the attribute Demo Greet.
And it creates this function that you can use for calling.
And if they function is assignable, it
has an assign property.
And then you can pass in a scope and the value you want
And then you are fully parameterized, so if you
choose to bind to a different thing, the whole thing works.
So those are the two ends.
You can read out of the scope, using the watch, and you can
also write to the scope.
And if you’re going to write to the scope, you probably
want to use something like parse to execute the
expression on your behalf.
Does that makes sense?
AUDIENCE: Why wouldn’t you just use the bracket notation?
MALE SPEAKER 1: Why not just use the bracket notation?
Because the bracket notation would only work for basic
But if I said name.first, the bracket notation would create
a property called name.first, which is not what you meant.
You meant to say the name property on the scope, and
then that object has a property called first.
And so it’s a different expression.
So all Angular expressions that very much look like
execute through the parse service.
Let’s see what else do I have [INAUDIBLE].
MALE SPEAKER 1: Yes?
that’s just something that you kind of know?
MALE SPEAKER 1: So no.
You can find out this easily.
And the way you find this out is you say,
AUDIENCE: Can you repeat the question?
MALE SPEAKER 1: Yeah, so how do know that
you’re inside of Angular?
When I click, this is a stack trace at
that particular location.
And if you look at this particular stack trace, you’ll
notice that we’re essentially in jQuery land.
In other words, what you’re looking
for is an apply function.
There is no apply function below you.
So all operations inside of Angular need
to happen in apply.
And usually, all of the directives properly transition
you into the apply.
So unless you’re writing your own directive, when you’re
using our directives inside your controllers, you never
have to worry about applies.
It should just automatically just happen
at the right moment.
But if you’re outside, and you’re writing your own
directive, you basically are outside of it, and you have
know when to transition into it.
Does that answer your question?
It still seems [? cryptic. ?]
MALE SPEAKER 1: So basically, the event comes from the
browser, whether it’s a user event or [? exit char ?]
event, or whatever, a timer event.
And it has to pass through apply before we can do the
operations on their model.
But you just have to know.
MALE SPEAKER 2: Well, whenever you’re using Angular APIs,
MALE SPEAKER 1: Microphone, sir?
There’s one right over there.
MALE SPEAKER 1: You know, I looked for it, and I
MALE SPEAKER 2: So whenever you are interacting with
Angular APIs, this is all taken care of for you.
Whenever you’re building directives is when you
typically interact with DOM events or jQuery plug-ins.
And that’s when you’re not in the Angular world.
And that’s what you need to know about apply.
But directive is something that you usually build when
you are more advanced because of all the existing APIs.
So I think you should be fine.
As long as you know if you’re using Angular
If the event is coming from jQuery or DOM,
you need call apply.
MALE SPEAKER 1: OK, so this is the basic directive.
And so what we have done is, basically,
we created an attribute.
Oh, we forgot different ways of invoking it.
So before we move on, I want to show you one more thing.
So this particular thing, we say Demo Greet.
But it turns out you can also say x-demo.
You can also say demo-greet if you like HTML.
These are all equivalent.
You can say data-demo if you really insist
on being HTML compliant.
But you ‘re going to do even crazier stuff.
You can say class demo, I think it’s a colon, like that.
And so when I refresh this, it’s not going to work.
And the reason it’s not going to work because, by default,
we only bind to attributes.
And so we have to help it out and say restrict.
And we say we can do be attribute or
you can be a class.
Now why would you want to bind to class?
Well, you would like to bind to class because sometimes
you’re using libraries like Bootstrap.
And these libraries say, well, if you put these classes then
the right stuff happens.
And what you really want to say using Angular is like,
well, if you put those classes, not only the right
stuff renders, but the right behavior is going
to be there as well.
And so you want to execute that stuff as well.
And so you can do this, and you can also do this.
You can also do Demo Greet as a tag.
Unfortunately, this one also takes an argument, so we have
And this will also work as expected.
So you have a choice in the way you structure your stuff.
MALE SPEAKER 1: There’s restrictions.
There is no old browsers.
There’s only IE and everything else.
So in IE, yes, good question.
IE, it turns out, likes the XML namespace provided that
you put XML namespace declarations on the top.
So that’s kind of a good strategy for IE.
But it doesn’t like elements that it’s not familiar with.
And there’s a page on our documentation that
specifically talks about all the quirks of IE.
And the way you get IE to cooperate is, if you have to
declare all of the elements ahead of time.
And the way you declare them is, you say document.create.
And then, all a sudden, something magically starts
working inside of IE.
Read the documentation.
I think it’s fixed in IE 9.
But yes, we don’t recommend doing this by default, and
only because of IE 8.
You can make it work if you do extra tricks that I’ve
described over there.
But by default this is not going to fly with IE 8.
OK, let’s move on to the next thing.
So this is basic directive.
So let’s talk about, now, something that we would call
And so [INAUDIBLE] me smaller.
OK so here’s a basically typical web page.
Usually, on the upper right corner, you have an I am.
And that’s who you’re logged in as.
And then, in this particular case, I’m actually looking at
a set of developers.
And this is the Angular team.
And the code for rendering this guy and the code for
rendering this guy is the same thing.
Basically, it’s over here.
All right, saying, if you have these divs and these images
and this H1, and the set of classes placed over there,
then we will render something that looks like
the right hand side.
But because we have to do it twice, we basically are
repeating this code along with this code over here.
And so now we’re getting into the world of reusable
We know that repeating yourself is a bad idea inside
of code, and you want to be able to reuse.
me extract the function.
And let me call that function because it’s the same thing
that has to happen in two different locations.
And so, in essence, what we want to do it’s the same exact
thing, but in HTML.
I want to say, this is a reusable component.
Let’s pull it out and reuse it.
So the first thing we’re going to do is
pull it out like this.
And we’re going to put it inside of a separate HTML
And then we have to do a couple of things.
We have to say, we have a directive called profile.
And let’s say it’s going to be an element-based directive.
And let’s point it to that file over there.
And now, we can go back to our index.html, so obviously, if I
refresh now, it’s going to be all broken.
But if I say profile, then now the profile comes up.
And if I copy the same exact thing over here, then voila,
I’m back in business.
So that’s nice, but there’s a couple of problems with it.
Well, this makes all kinds of assumptions.
Mainly, that it assumes that the thing that you’re going
So it kind of makes sense over here because, Demo, the
controller, says that the email is me.
But when we’re inside of the HTML, and we’re iterating over
all the developers, we have to make it email.
And if we change it to dev, and we run it,
whoa, what just happened?
How comes there’s Mieszko everywhere.
Like, I might like myself, but this is not the
thing you want to see.
Well, what’s happening is that the profile assumed that the
thing to look at is email.
And it worked because we said ng-repeat email in developers.
But when we used the different variable, the profile still
And it’s because the repeater doesn’t override the email.
The way the scopes work, you look at the parent scope.
And the parents scope happens to contain the
email for the user.
And so we have the situation where the user’s being
This is not what you want.
what’s nice about this function is that inside of
this function you’re kind of encapsulated
from the outside world.
You have your private variables.
And you don’t have to worry about messing anybody up.
And if I have a variable called x, I don’t have to
worry that the function that called me also happens to
I know it’s a different scoping.
So let’s create a linking function here.
And so the basic problem is that if I’m in some of the
scope, and, I say scope.league is equal to–
and I refresh, notice that I was able to clobber the
Not only am I might not playing nice because I’m just
simply assuming that the outside world is what– there
has to be this special thing called email, otherwise, I
But also, if I happen to have an internal state inside of
it, I’m clobbering it.
Now there’s a lot of ways to solve it.
And the simplest way is to say, well,
we have a new scope.
So this directive needs to have a new scope.
And now you see that we’re no longer clobbering
And why are we no longer clobbering [? league ?] is
because if you look at the scopes, the outermost scope
has the email, which is myself.
And the individual iterations, they have a developer called
Mieszko, a developer [? Minar ?], developer
And each one is writing it’s own scope.
Each one has its own private kind of place to play.
So now we solved one particular problem, that we
are no longer leaking to the outside world.
But we haven’t solved the other problem that we are not
It’s essentially as if you called a
function that has no arguments.
And the arguments are in the global location.
You just have to write into a global location, and then you
And then that function knows to look
in the global location.
This is not how we code.
We know this is a recipe for disaster.
So what you really want to do is say, actually, I want to
have my own private world.
But not only do I want to have my private world, is, I want
to be able to take variables from the outside.
And so, in this particular case, if we look at our HTML,
it turns out that this email is what we’re interested
because email is used in both of these locations.
So what we want to say is that email is what we want.
Now where do we get email from, is the question.
And we can do a couple of things.
And we can say equals.
And then you can go to index.html and then say–
so first of all, if I do this, and I refresh, then
everybody’s broken because I didn’t pass email into it.
So what we have to do this is we have to say
email equals email.
And voila, this guy works.
And we can do the same thing over here.
We can say email equals–
this time we bind it to developer, and, voila, the
So now we basically have segregated ourselves, not only
from the global state outside of us, so we don’t actually
clobber or anything, but also we have proper parameters that
we’re passing into it.
Now, at this point, a lot of people say, well, why this?
What if this is what I want?
So if I do this, obviously, it’s not going to work
because, well, that’s not–
so I have to be consistent.
I also have to change it over here.
It’s not going to work because we’re actually passing the
This kind of confusing because it’s double escaped.
But if we look at the HTML, and we find a directive–
we find the profile–
we see that the email–
Sorry, why is this?
I think I broke something.
It is completely broken because it’s trying to read it
So let me just disable this for a second.
And what I want to show you it is that the profile has an
email that should’ve been set.
OK, I’m not sure why it’s not showing up.
But anyways, the way to do this is to say, we want to
read the attribute.
So whether you specify equals or you specify @ sign, you’re
basically deciding whether you want to use this style versus
So you say, well, why do we have two styles?
What’s the difference?
Well, it turns out there is a significant difference.
And the difference is, basically, that, in this case,
you’re getting back a string.
Because what you’re saying is, I’m updating this attributes
And then the component is watching that attribute, and
the attributes have to be strings.
So you cannot pass anything but a string here.
Whereas, if the first case we had, what we’re really saying
is that we’re taking the expression.
And the expression could be an object.
And so what we’re getting is a reference to the object.
So the two are really different beasts.
And what it really comes down to is, are you actually
intending people to modify the attribute.
Does the modification of the attribute actually make sense
in this particular case.
So for example, ng-click, you don’t really need to modify
the attribute ng-click, that’s meaningless, right?
But if you have image source, then you put double curlies
because you’re saying, I actually want to modify the
attribute because that makes what the browser is actually
Kind of make sense?
MALE SPEAKER 1: Yeah, so if you want to pass a URL, should
we pass it as a string or a curly.
That’s totally up to you.
It’s kind of your decision, unless Igor has an opinion
It’s hard to have a set of rules that say, oh, you have
to do this versus that.
It kind of depends on the context of the component.
If I want to simulate something that behaves like an
image tag, then obviously I’m going to use double curly
because I want to simulate the fact that changing the
attribute has a behavior.
If I have a full on component, then I will most likely use as
a reference to an object rather than as double curlies.
AUDIENCE: Let’s say if there’s a link, and I want to render
it as a link in the page, which I can click later on–
MALE SPEAKER 1: That’s independent because the way
that the outside world communicates with the
component is independent to [? where ?] the component
actually renders the link.
So this is how you would render it inside of the
And that’s up to you to decide how the rendering happens.
But keep in mind that the @ sign, the moment you’re using
an attribute, you’re saying, what you’re
getting back is a string.
So the other advantage of a string is that you can have
interpolation going on inside of the double curlies.
So you can say something like email/abc.
And then if you run it, you actually see that abc got
added to it, to each of the– well, actually, just here
because of the top one.
So if what you want is to give the user the ability to have
interpolation, then you probably want double curlies.
If what you want is actually get a reference to an object,
then interpolation is meaningless because
interpolation always gives you a string.
AUDIENCE: Thank you.
MALE SPEAKER 1: OK, I think that’s all for this guy.
Any other questions before we go to the next [? stop? ?]
OK, so let’s talk about the most complicated thing that
people always get confused about.
Let’s talk about transclusion.
So the component I showed you is nice because it
encapsulated a piece of code.
But the problem with that component is that that’s the
That component cannot have other components inside of it.
Let me rephrase that–
the component itself can have components in there, but it’s
What you want is to declare a component like this, where you
are wrapping something, in this case, a simple
interpolation, inside of the component in there.
So what you’re saying is, take the content of the components.
So let’s say I’m a zippy.
Everybody knows what a zippy is, right?
It kind of opens up and closes like this.
Currently, there’s no content.
We’ll put it in a second in there.
But the key is that the content itself is getting–
normally, the component that we have showed you a second
ago does not allow for the content of that profile to
The profile was always empty.
There was nothing inside of it.
Does that makes sense?
Some people look still confused.
Anybody still confused on this?
We’ll wait for the plane to pass.
OK, so what we want is, we want to pass hello in.
And so let’s have a look what’s happening in here.
So if you look at HTML, here’s a zippy.
And if you expand zippy, you’ll see that zippy got
replaced by its content.
So where’s the content come from?
Well, here’s a directive.
And the content for zippy comes from here.
And so what happens is that the zippy content clobbers the
content that was there originally.
And because of this clobbering, it is not possible
to nest directives.
But that’s not very useful because there are a lot of
directives you can think of like tabs, or zippy, or
window, or a modal dialogue box, although that’s not a
very good use case–
that you would like to model as, hey, there’s this thing
that goes around and then I want to be able to put the
And I want to be able to put different content depending on
where I to initiate this particular component.
And so this is what transclusion is all about.
So let’s go back to the directive.
So we want to basically say to the system is, the zippy
contains the content.
So you say transclude is true.
And so before the directive places its rendering HTML in
its place, it pulls out the content and says, I’m going to
save this for later.
And so the next thing we have to do is, we have to, inside
of the template, of the directive, say, well, where do
we want to put it back into?
And so we do this by saying ng-transclude.
Does that makes sense?
And then, when we refresh?
Voila, the Hello world from the
outside went to the inside.
So now let’s talk about this some more.
So let’s have a name here.
So I have two fields, greeting and world.
So notice the greeting changes the top portion.
And this one changes the inside of the component.
So if you look at the code, the greeting changes the
title, which we just talked about.
We can use double curlies for the interpolation.
And the content is hello name, but really the content could
You could put another zippy in there, or nest them, or
other components, et cetera.
But let’s just keep it simple.
Let’s just have hello name in there.
So what’s interesting is that, think about how scopes are.
This name is actually a child of the zippy.
So let’s go to the zippy.
And it would be a tragedy of encapsulation if I could say
esc name equally like this, and that would clobber the
Do you see what the issue is?
If I wrote to name, which just happened to be the name that
is used over here, then because the content got
transcluded, it got copied to me, as a child, I would be
clobbering the name.
And therefore the copied content wouldn’t behave the
way you would think it would behave.
And so now we have to do a little bit of [? dance ?] with
scopes in order to make this thing possible.
So what we want to do is say, look, the stuff that goes
inside of it, I know it’s inside of another directive,
but that directive needs to be isolated for all the good
reasons we talked about earlier.
So it has to have its own scope so that it’s isolated.
We talked about it earlier how the creation of the scope
creates isolation, so we don’t leak content outside.
But also, it means that the thing that we copied, in this
case, the hello name, has to have a scope that is not a
child scope of the component.
Because if it would be a child scope of the component, it
would see all the attributes, all of the
properties on the scope.
And so the thing I just showed you would clobber name.
So by writing into the name inside of the scope, I would
clobber it for the transcluded content.
And it would no longer behave as you would expect.
So what the transclusion does is, not only does it pull out
the content, but it also pulls the content
in the correct scope.
So it copies the scope, it creates a new child scope.
And it actually creates the two scopes as siblings.
So in other words, the component itself and the
transcluded scopes are siblings next to each other so
that they don’t inherit from each other in order to create
the correct illusion of isolation.
Does that make sense?
AUDIENCE: They’re both children of the–
MALE SPEAKER 1: The parents scope, yes.
AUDIENCE: But the isolated scope doesn’t [INAUDIBLE].
MALE SPEAKER 1: Right, so isolated scope is not
I showed you the earlier problem that if I didn’t
properly provide a user email, it defaulted to the parent
email and then rendered the wrong thing.
So I want to make sure that it doesn’t happen.
So if I forget to initialize something inside of a
component, I don’t accidentally
inherit from somebody.
So the components have a non-inheriting scope.
So that isolates the component from the context that
But we have a second problem, which is that we have to
isolate the transcluded content from the component
itself because you can imagine a component, and a component
has a hole where the thing got moved into.
MALE SPEAKER 2: Can you say that again?
MALE SPEAKER 1: OK, so if we didn’t do any of these
gymnastics, then what we would have is, we would have a
component, and the problem with that component would be
that it would see everything that is around it.
function that would inherit all the global properties from
And that would mean that if you would forget to declare a
property inside of the component, and that such a
property would just happen to be declared above you, you
would see the wrong one.
And if you don’t want to do that.
You want to basically say, no, no, no, as a component, you
don’t get to see the parent attribute because that breaks
So you flip a switch and say, for all components, we do not
And that’s how we isolate the component.
So that’s the first problem.
The second problem is, is if you copy the content, in this
case, if you copy the hello name, hello name right here,
and move it inside of a zippy, inside of the body– because
if you look into here, this is where the hello
name ended up in here.
If you move it over there, then normal rules are, oh this
thing would inherit from the parent and
the parent is zippy.
But that would means that it would inherit from a scope
that doesn’t see the parent, which means this particular
scope wouldn’t be able to get to the name.
So by copying the hello name into the component, you can no
longer see the name.
Worse, not only can you not see the name, if the name is
happens to be declared inside of the component, now you see
the component’s name.
And that’s not what we expect to happen with normal
So what we have to do is, we have to a little bit of
gymnastics with the scopes, and we have to
make them as siblings.
And basically, the parent scope of this binding is the
And the parents scope of the zippy is the controller.
But one scope inherits.
So in this case, we want to inherit, so that if I refer to
a name, I’m actually going to get the name from the
In this case, I don’t want to inherit because I’m going to
basically say, if I happens to refer to a name, and I didn’t
declare it inside of the component, I shouldn’t be
getting the one from parent.
Does that make sense?
AUDIENCE: So only the zippy is an isolate.
MALE SPEAKER 1: Only the zippy is an isolate.
The transcluded scope is not an isolate.
They don’t inherit, so you can’t implicitly grab the
parents from an isolated scope.
Could you explicitly, with the–
MALE SPEAKER 1: $parent?
Yes, you can definitely get it using the $parent.
So the only thing you get is what you declare inside of
And you can use the equals @ sign for attributes, and
there’s also an ampersand for expressions that you can
execute later, which we haven’t talked about.
But it’s in the documentation.
And so the way to think about it is, you have a function
That’s what component wants to be.
Anyways, so this wraps up the directives.
Hopefully, I’ve answered many of your questions.
And they’re less mysterious.
And again, I want to stress that directives is really the
unique thing about Angular that nobody else has.
There’s no other framework that I know of that can do
this trick where it basically gives you the ability to make
your own directives and your own attributes and build
Normally, we build applications because we just
plaster div and div on top of a div and
put bunch of classes.
But with this, you can build yourself a syntax.
You can say, hey, I really want to have a zippy.
So I don’t want to create a whole set of divs to make a
zippy, I just want to say, I want to have a zippy.
I want to have a tab.
I just want to say, have a tab, and you get it.
And this is why it’s so natural for the Flex
developers, which, I believe some of them are ex-Flex
It’s not embarrassing, you can raise your hand.
I’m an ex-Flex guy as well.
This is why it’s so natural for them because in Flex, this
is the mode of operation where you just use MXML to declare
your structure and off you–