I am very new to AngularJS. can anybody explain me the difference among these AngularJS operators: &, @ and =
when isolating scope with proper example.
This question is related to
javascript
angularjs
@: one-way binding
=: two-way binding
&: function binding
Not my fiddle, but http://jsfiddle.net/maxisam/QrCXh/ shows the difference. The key piece is:
scope:{
/* NOTE: Normally I would set my attributes and bindings
to be the same name but I wanted to delineate between
parent and isolated scope. */
isolatedAttributeFoo:'@attributeFoo',
isolatedBindingFoo:'=bindingFoo',
isolatedExpressionFoo:'&'
}
It took me a hell of a long time to really get a handle on this. The key to me was in understanding that "@" is for stuff that you want evaluated in situ and passed through into the directive as a constant where "=" actually passes the object itself.
There's a nice blog post that explains this this at: http://blog.ramses.io/technical/AngularJS-the-difference-between-@-&-and-=-when-declaring-directives-using-isolate-scopes
I would like to explain the concepts from the perspective of JavaScript prototype inheritance. Hopefully help to understand.
There are three options to define the scope of a directive:
scope: false
: Angular default. The directive's scope is exactly the one of its parent scope (parentScope
).scope: true
: Angular creates a scope for this directive. The scope prototypically inherits from parentScope
.scope: {...}
: isolated scope is explained below. Specifying scope: {...}
defines an isolatedScope
. An isolatedScope
does not inherit properties from parentScope
, although isolatedScope.$parent === parentScope
. It is defined through:
app.directive("myDirective", function() {
return {
scope: {
... // defining scope means that 'no inheritance from parent'.
},
}
})
isolatedScope
does not have direct access to parentScope
. But sometimes the directive needs to communicate with the parentScope
. They communicate through @
, =
and &
. The topic about using symbols @
, =
and &
are talking about scenarios using isolatedScope
.
It is usually used for some common components shared by different pages, like Modals. An isolated scope prevents polluting the global scope and is easy to share among pages.
Here is a basic directive: http://jsfiddle.net/7t984sf9/5/. An image to illustrate is:
@
: one-way binding@
simply passes the property from parentScope
to isolatedScope
. It is called one-way binding
, which means you cannot modify the value of parentScope
properties. If you are familiar with JavaScript inheritance, you can understand these two scenarios easily:
If the binding property is a primitive type, like interpolatedProp
in the example: you can modify interpolatedProp
, but parentProp1
would not be changed. However, if you change the value of parentProp1
, interpolatedProp
will be overwritten with the new value (when angular $digest).
If the binding property is some object, like parentObj
: since the one passed to isolatedScope
is a reference, modifying the value will trigger this error:
TypeError: Cannot assign to read only property 'x' of {"x":1,"y":2}
=
: two-way binding=
is called two-way binding
, which means any modification in childScope
will also update the value in parentScope
, and vice versa. This rule works for both primitives and objects. If you change the binding type of parentObj
to be =
, you will find that you can modify the value of parentObj.x
. A typical example is ngModel
.
&
: function binding&
allows the directive to call some parentScope
function and pass in some value from the directive. For example, check JSFiddle: & in directive scope.
Define a clickable template in the directive like:
<div ng-click="vm.onCheck({valueFromDirective: vm.value + ' is from the directive'})">
And use the directive like:
<div my-checkbox value="vm.myValue" on-check="vm.myFunction(valueFromDirective)"></div>
The variable valueFromDirective
is passed from the directive to the parent controller through {valueFromDirective: ...
.
Reference: Understanding Scopes
AngularJS – Isolated Scopes – @ vs = vs &
Short examples with explanation are available at below link :
http://www.codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs
@ – one way binding
In directive:
scope : { nameValue : "@name" }
In view:
<my-widget name="{{nameFromParentScope}}"></my-widget>
= – two way binding
In directive:
scope : { nameValue : "=name" },
link : function(scope) {
scope.name = "Changing the value here will get reflected in parent scope value";
}
In view:
<my-widget name="{{nameFromParentScope}}"></my-widget>
& – Function call
In directive :
scope : { nameChange : "&" }
link : function(scope) {
scope.nameChange({newName:"NameFromIsolaltedScope"});
}
In view:
<my-widget nameChange="onNameChange(newName)"></my-widget>
Source: Stackoverflow.com