Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One-way binding in Angular directives

The official Angular documentation for compile discusses the one-way binding type <.

In the Angular community, I see @ commonly referred to as the "one-way binding type".

What gives? The @ doesn't seem to me to be true one-way binding since it's just evaluating the expression and setting a string. The < seems to be more similar to = with the exception that the binding is only one-way.

My guess is that < was introduced recently which would explain why @ used to be referred to as the one-way binding type. (Which it kind of is, but not quite)

Hopefully someone with more Angular experience can set things straight for me! :)


Update: @aaronmallen commented and confirmed that < was added recently (Angular 1.5).

To further clarify things, when should I use @ vs <?

like image 520
rinogo Avatar asked Aug 04 '16 20:08

rinogo


2 Answers

There are two ways of doing one way binding in Angular 1.x depending on which version you have

<1.5

@ binding binds a literal value from the parent into the isolate scope. So you can do this:

<cat name="Fluffy" age="12"></cat>

You can think of this as one way binding. Because you are binding a literal, the data won't come back out, because there's nothing for it to be assigned to.

In older version of Angular (<1.5), we used @ plus curlies {{}} when we wanted one way binding. The curlies converted the expression to a literal before transport, so we were passing in a literal:

<cat name="{{$ctrl.catName}}" age="{{$ctrl.catAge}}"></cat>

Because the curly brace expression was evaluated to a literal, and then passed in as a literal to the directive. The data couldn't come back up again, because the curlies have been evaluated to a string, so there's nothing for the data to be assigned to.

You'll still find this method used in many tutorials. It is now obsolete, and you should probably avoid it.

1.5 +

In 1.5 we got < binding. This lets us one way bind without the curlies. We can now do this:

<cat name="$ctrl.catName" age="$ctrl.catAge"></cat>

Unlike = binding, if the value changes on the isolate, the change won't be reflected in the parent. The effect is the same, but the syntax is much nicer.

like image 194
superluminary Avatar answered Nov 22 '22 17:11

superluminary


If you're interested in not having the value re-evaluated you could use one-time binding in your views with:

<span>{{::foo}}</span>

https://docs.angularjs.org/guide/expression#one-time-binding

But to answer your question specifically the '<' binding was introduced in Angular 1.5 and essentially means if you pass an attribute to your directive and then update it in the controller it will not update in the directive. The '@' binding is for specifically passing a string value, it does not necessarily one-way bind the value.

Sources:

  • A good read on Angular 1.5 bindings
  • Official documentation on scope bindings
like image 20
aaronmallen Avatar answered Nov 22 '22 15:11

aaronmallen