Étant enveloppé par une directive, comment puis-je accéder à sa portée ?
-
21-12-2019 - |
Question
Comment puis-je accéder à la portée isolée de la directive dans le corps de la directive ?Mon DOM ressemble à ceci :
<div ng-app="app">
<directive>
<p>boolProperty: {{boolProperty|json}}</p>
</directive>
</div>
Le boolProperty
est attribué à l'intérieur de la directive link
fonction:
angular.module("app", []).directive("directive", function() {
return {
scope: {},
link: function($scope) {
$scope.boolProperty = true;
}
};
});
Le problème c'est que l'enfant <p>
à l'intérieur de la directive se lie au parent champ d'application, et non le champ d'application isolé de la directive.Comment puis-je surmonter cela ?
La solution
Vous avez oublié deux choses :
- Par défaut, AngularJS utilise la restriction d'attribut, donc dans votre cas, dans la définition de directive, vous devez spécifier
restrict: "E"
- Vous devez utiliser une portée enfant, mais pas isolée.Alors réglé
scope: true
pour hériter de la portée de la vue parent.
Voir le violon mis à jour http://jsfiddle.net/Y9g4q/1/.
Bonne chance.
Autres conseils
Il y a quelques problèmes dans votre code.
- L'option de restriction par défaut est
A
for attribut donc de toute façon votre directive ne sera pas compilée car vous l'utilisez comme élément.Utiliserrestrict: 'E'
pour que ça marche. Selon la documentation, la portée de l'élément transclus n'est pas une portée enfant de la directive mais une portée sœur.Donc
boolProperty
sera toujours indéfini ou vide.Vous devez donc remonter le niveau de portée et trouver le bon frère.<div ng-app="app"> <directive> <p>boolProperty: {{$parent.$$childHead.boolProperty}}</p> </directive> </div>
et il faut utiliser la transclusion dans la directive comme :
angular.module("app", []).directive("directive", function() {
return {
restrict: 'E',
scope: {},
transclude: true,
template: '<div ng-transclude></div>',
link: function(scope) {
scope.boolProperty = true;
}
};
});
Cependant, cette approche n'est pas conseillée et s'interrompra plus tard si vous ajoutez un nouveau contrôleur avant la directive car la portée transcluse devient le 2ème frère contrairement au 1er comme avant.
<div ng-app="app">
<div ng-controller="OneCtrl"></div>
<directive>
<p>boolProperty: {{$parent.$$childHead.boolProperty || $parent.$$childHead.$$nextSibling.boolProperty}}</p>
</directive>
</div>
Voici la Démo de travail.L'approche que j'ai mentionnée n'est pas idéale, alors utilisez-la à vos propres risques.La réponse de @CodeHater est celle que vous devriez choisir.Je voulais juste expliquer pourquoi cela n'a pas fonctionné pour vous.
Du documents:
As the name suggests, the isolate scope of the directive isolates everything except models that you've explicitly added to the scope: {} hash object. This is helpful when building reusable components because it prevents a component from changing your model state except for the models that you explicitly pass in.
Il semble que vous deviez ajouter explicitement boolProperty
à scope
.
<div ng-app="app" ng-controller="ctrl">
<directive bool="boolProperty">
<p>boolProperty: {{boolProperty|json}}</p>
</directive>
</div>
JS
angular.module("app", []).controller("ctrl",function($scope){
$scope.boolProperty = false;
}).directive("directive", function() {
return {
restrict:"E",
scope: {boolProperty:'=bool'},
link: function($scope) {
$scope.boolProperty = "i'm a boolean property";
}
};
});
Voici mis à jour violon.