Angularjs: how to pass scope variables to a directive?

50,221

Solution 1

Read Attributes/observing interpolated attributes section of the directive docs. During the link phase the attributes haven't been set.

There are several ways including using attrs.$observe or $timeout.

app.directive('createControl', function($timeout){
 return function(scope, element, attrs){
      attrs.$observe('createControl',function(){
        console.log(' type:',attrs.createControl);
         element.text('Directive text, type is: '+attrs.createControl);
      });
  }
}) ;

DEMO

Solution 2

    app.directive('createControl', function() {
      return {
        scope: {
          createControl:'='
        },
        link: function(scope, element, attrs){    
           element.text(scope.createControl);    
        }      
      }
    })  

  <div class="control-group" ng-repeat="v in [{type:'green'}, {type:'brown'}]">
    <div create-control="v.type"></div>
   </div>

Solution 3

If v.type may change (i.e., you really need to use interpolation -- the {{}}s), use @charlietfl's or @Joe's answser, depending on the type of scope you want your directive to have.

If v.type will not change (i.e., your link function only needs to get the values once, and those values are guaranteed to be set when your link function runs), you can use $parse or $eval instead. This has a slight performance advantage in that no $watches are created. (With $observe() and =, Angular sets up $watches, which are evaluated every digest cycle.)

<div create-control="v.type"></div>
app.directive('createControl', function ($parse) {
    return function (scope, element, attrs) {
        console.log('$eval type:', scope.$eval(attrs.createControl));
        var type = $parse(attrs.createControl)(scope);
        console.log('$parse type:', type);
        element.text('Directive text, type is: ' + type);
    }
});

demo

Share:
50,221

Related videos on Youtube

I159
Author by

I159

Updated on March 04, 2020

Comments

  • I159
    I159 about 4 years

    I am trying to use directive to create and append several tags to a <div> as shown below:

    module.directive('createControl', function(){
      return function(scope, element, attrs){    
        console.log(attrs.createControl); // undefined     
      }                                          
    });                                         
    
    
    <div class="control-group" ng-repeat="(k, v) in selectedControls">
      <div create-control="{{ v.type }}"></div>
    </div>
    

    In attrs I have this construction:

    $$element: b.fn.b.init[1]
    $$observers: Object
    $attr: Object
    createControl: "date"
    style: "margin-right: 15px"
    __proto__: Object
    

    But when I try to use attrs.createControl I get undefined and I do not understand why. Actual question: how to pass scope variable to a directive?

  • Jackie
    Jackie over 9 years
    Not so sure I get this one, how does it now the div is the directive?
  • isherwood
    isherwood over 9 years
    Jackie, Angular looks for a directive (camelCase) that matches the create-control (hyphenated lower-case) attribute.
  • phil294
    phil294 about 8 years
    explanations, will hopefully help someone else: 1.) '@' will not work, for whatever reason. 2.) can also be applied using multiple variables, like <create-control val1="v.type" value-two="x.y"></create-control>. Note that value-two also becomes camelCase in the directive scope definition (valueTwo). 3.) there must be no {{}} around the variable (such as, NO ...="{{v.type}}")