web-dev-qa-db-fra.com

Angularjs: comment passer des variables de portée à une directive?

J'essaie d'utiliser la directive pour créer et ajouter plusieurs balises à un <div> comme indiqué ci-dessous:

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>

En attrs j'ai cette construction:

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

Mais quand j'essaie d'utiliser attrs.createControl Je reçois undefined et je ne comprends pas pourquoi. Question réelle: comment passer une variable de portée à une directive?

27
I159

Lire Attributs/observer les attributs interpolés de la section documentation de la directive . Pendant la phase de liaison, les attributs n'ont pas été définis.

Il existe plusieurs façons, notamment d'utiliser attrs.$observe ou $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

15
charlietfl
    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>
34
Joe Hanink

Si v.type Peut changer (c'est-à-dire que vous devez vraiment utiliser l'interpolation - les {{}} s), utilisez le répondeur @ charlietfl ou @ Joe, selon le type de portée que vous voulez que votre directive ait.

Si v.type Ne changera pas (c'est-à-dire que votre fonction de lien n'a besoin d'obtenir les valeurs qu'une seule fois, et que ces valeurs sont garanties d'être définies lorsque votre fonction de lien s'exécute), vous pouvez utiliser $ parse = ou $ eval à la place. Cela présente un léger avantage en termes de performances dans la mesure où aucune montre $ n'est créée. (Avec $observe() et =, Angular configure $ montres, qui sont évaluées à chaque cycle de résumé.)

<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

15
Mark Rajcok