[angularjs] What is the difference between '@' and '=' in directive scope in AngularJS?

Why do I have to use "{{title}}" with '@' and "title" with '='?

@ binds a local/directive scope property to the evaluated value of the DOM attribute. If you use title=title1 or title="title1", the value of DOM attribute "title" is simply the string title1. If you use title="{{title}}", the value of the DOM attribute "title" is the interpolated value of {{title}}, hence the string will be whatever parent scope property "title" is currently set to. Since attribute values are always strings, you will always end up with a string value for this property in the directive's scope when using @.

= binds a local/directive scope property to a parent scope property. So with =, you use the parent model/scope property name as the value of the DOM attribute. You can't use {{}}s with =.

With @, you can do things like title="{{title}} and then some" -- {{title}} is interpolated, then the string "and them some" is concatenated with it. The final concatenated string is what the local/directive scope property gets. (You can't do this with =, only @.)

With @, you will need to use attr.$observe('title', function(value) { ... }) if you need to use the value in your link(ing) function. E.g., if(scope.title == "...") won't work like you expect. Note that this means you can only access this attribute asynchronously. You don't need to use $observe() if you are only using the value in a template. E.g., template: '<div>{{title}}</div>'.

With =, you don't need to use $observe.

Can I also access the parent scope directly, without decorating my element with an attribute?

Yes, but only if you don't use an isolate scope. Remove this line from your directive

scope: { ... }

and then your directive will not create a new scope. It will use the parent scope. You can then access all of the parent scope properties directly.

The documentation says "Often it's desirable to pass data from the isolated scope via an expression and to the parent scope", but that seems to work fine with bidirectional binding too. Why would the expression route be better?

Yes, bidirectional binding allows the local/directive scope and the parent scope to share data. "Expression binding" allows the directive to call an expression (or function) defined by a DOM attribute -- and you can also pass data as arguments to the expression or function. So, if you don't need to share data with the parent -- you just want to call a function defined in the parent scope -- you can use the & syntax.

See also

Examples related to angularjs

AngularJs directive not updating another directive's scope ERROR in Cannot find module 'node-sass' CORS: credentials mode is 'include' CORS error :Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response WebSocket connection failed: Error during WebSocket handshake: Unexpected response code: 400 Print Html template in Angular 2 (ng-print in Angular 2) $http.get(...).success is not a function Angular 1.6.0: "Possibly unhandled rejection" error Find object by its property in array of objects with AngularJS way Error: Cannot invoke an expression whose type lacks a call signature

Examples related to angularjs-directive

Angular2 - Input Field To Accept Only Numbers Use of symbols '@', '&', '=' and '>' in custom directive's scope binding: AngularJS ng-change not working on a text input Controller not a function, got undefined, while defining controllers globally Find child element in AngularJS directive Angular directives - when and how to use compile, controller, pre-link and post-link How to validate email id in angularJs using ng-pattern Enable/Disable Anchor Tags using AngularJS get original element from ng-click How to detect browser using angularjs?

Examples related to angularjs-scope

Use of symbols '@', '&', '=' and '>' in custom directive's scope binding: AngularJS How to call a function from another controller in angularjs? Detect if checkbox is checked or unchecked in Angular.js ng-change event $rootScope.$broadcast vs. $scope.$emit How to clear or stop timeInterval in angularjs? How do I inject a controller into another controller in AngularJS Controller not a function, got undefined, while defining controllers globally AngularJS - get element attributes values ng-if, not equal to? How to set the id attribute of a HTML element dynamically with angularjs (1.x)?

Examples related to isolated-scope

What is the difference between '@' and '=' in directive scope in AngularJS?