Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

exposing an object in angularjs directive scope, can't access properties

So, I have the following relatively simple Angularjs directive

app.directive('myDirective', function () {
      return {
          restrict: 'E',
          scope: {
              site: '@',
              index: '@'
          },
          template: '<div>{{site}}</div>',
          replace: true,

      }
  });

And here is where I call the directive in HTML

<div id="eventGraphic" class="span12">
    <my-directive ng-repeat="site in IEvent.sites" site="{{site}}" index="{{$index}}"></my-directive>
</div>

Which, given that each site is an object, produces this output (copied from browser)

{"name":"Hurlburt","_id":"5148bb6b79353be406000005","enclaves":[]}
{"name":"Walker Center","_id":"5148cca5436905781a000005","enclaves":[]}
{"name":"test1","_id":"5148ce94436905781a000006","enclaves":[]}
{"name":"JDIF","_id":"5148cf37436905781a000007","enclaves":[]} 

However, if I change the template in the directive to

 template: '<div>{{site.name}}</div>',

it does not produce any output. This seems like a fairly straightforward use case, any ideas what I could be doing wrong? The desired output would be just the name field in each object.

like image 982
user1048378 Avatar asked Mar 20 '13 18:03

user1048378


People also ask

What is the number of scopes allowed in an AngularJS application?

Each AngularJS application has exactly one root scope, but may have any number of child scopes.

What are the directive scopes in AngularJS?

The directive scope uses prefixes to achieve that. Using prefixes helps establish a two-way or one-way binding between parent and directive scopes, and also make calls to parent scope methods. To access any data in the parent scope requires passing the data at two places – the directive scope and the directive tag.

What is restrict in AngularJS directive?

Note: When you create a directive, it is restricted to attribute and elements only by default. In order to create directives that are triggered by class name, you need to use the restrict option. The restrict option is typically set to: 'A' - only matches attribute name.

What is attrs in AngularJS?

Using attrs you are able to access the attributes defined in your html tag like <fm-rating ng-model="$parent.restaurant.price" symbol="$" readonly="true"> So in this case you will have access to the symbol and readonly attributes.


1 Answers

You need to use '=' to map the object. '@' implies you're just passing a string value to the new scope.

app.directive('myDirective', function () {
      return {
          restrict: 'E',
          scope: {
              site: '=', //two-way binding
              index: '@' //just passing an attribute as a string.
          },
          template: '<div>{{site}}</div>',
          replace: true,

      }
  });

Then in your markup, don't use a binding in the attribute, just pass the expression:

<div id="eventGraphic" class="span12">
    <!-- below, site="site" is passing the expression (site) to
         the two way binding for your directive's scope,
         whereas index="{{$index}}" is actually evaluating the expression
         ($index) and passing it as a string to the index attribute,
         which is being put directly into the directive's scope as a string -->
    <my-directive ng-repeat="site in IEvent.sites" 
            site="site" 
            index="{{$index}}"></my-directive>
</div>
like image 173
Ben Lesh Avatar answered Sep 28 '22 14:09

Ben Lesh