0

I've been reading the AngularJS docs and found something that I still don't understand:

For cases where the attribute name is the same as the value you want to bind to inside the directive's scope, you can use this shorthand syntax:

...
scope: {
  // same as '=customer'
  customer: '='
},
...

Looking at the final example (my-tabs/my-pane) the code is this one:

.directive('myPane', function() {
  return {
    require: '^myTabs',
    restrict: 'E',
    transclude: true,
    scope: {
      title: '@'
    },
    link: function(scope, element, attrs, tabsCtrl) {
      tabsCtrl.addPane(scope);
    },
    templateUrl: 'my-pane.html'
  };
});

I've tried to change the '@' by '=' and the example breaks. So what is doing '@'? And why '=' neither '=title' are not working here?

3 Answers 3

1

When you use = you are specifying a two-way binding between the property of the parent scope and the one that will be created on the directive's scope. That means that the value of the attribute will usually be an identifier that matches a property on the parent scope.

When you use @ you are specifying a one-way binding. The result will always be a string. Changes to the property on the directive scope will not affect the parent scope (since the model is not a reference to a parent scope property).

In your example the title property is a literal string rather than a reference to a property on the parent scope. When you change the @ to = it breaks because there is no property with the right name on the parent scope.

This is documented under the $compile service.

Sign up to request clarification or add additional context in comments.

1 Comment

Great! I was reading from top-down so I haven't reached compiler yet. Imo it should be explained/reffered in directives as well.
1

In AngularJs directive,

Isolated scope variables can be declared in three ways

  1. @ this will take the argument as string, even if it is an Object/Array/Function
  2. = will bind two way, So you can get Object/Array/Function inside the directive, and changes inside the directive will reflect in original/parent scope
  3. & will bind in one way, you can get the value of the attribute (i.e Object/Array/Function) inside the directive, but if you change the value, it wont change the value of the attribute in parent scope

In case 2, 3: If you don't define variables in the parent scope, they will be undefined, So define them properly.

Option 3: Is one way, So it is a good way to bind callback functions to the directive.

Comments

0

You can take a look at compile documentation There are explanations for all three cases:

@ or @attr - bind a local scope property to the value of DOM attribute. The result is always a string since DOM attributes are strings. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given and widget definition of scope: { localName:'@myAttr' }, then widget scope property localName will reflect the interpolated value of hello {{name}}. As the name attribute changes so will the localName property on the widget scope. The name is read from the parent scope (not component scope).

So in this case title is an attribute, not a variable.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.