Existe-t-il un moyen de transmettre des variables utilisant des attributs à une directive sans créer de nouvelle portée?
HTML
<div ng-click='back()' button='go back'></div>
JS
.directive('button', function () {
return {
scope: {
button: '@'
},
template: "<div><div another-directive></div>{{button}}</div>",
replace: true
}
})
Le problème est que la ng-click='back()'
fait désormais référence à la portée de la directive. Je peux toujours faire ng-click='$parent.back()'
mais ce n'est pas ce que je veux.
Par défaut, les directives ne créent pas de nouvelle étendue. Si vous voulez rendre cela explicite, ajoutez scope: false
À votre directive:
<div ng-click='back()' button='go back!'></div>
angular.module('myApp').directive("button", function () {
return {
scope: false, // this is the default, so you could remove this line
template: "<div><div another-directive></div>{{button}}</div>",
replace: true,
link: function (scope, element, attrs) {
scope.button = attrs.button;
}
};
});
Puisqu'une nouvelle propriété, button
, est en cours de création sur la portée, vous devez normalement créer une nouvelle portée enfant en utilisant scope: true
Comme @ ardentum-c l'a fait dans sa réponse. La nouvelle portée héritera prototypiquement de la portée parent, c'est pourquoi vous n'avez pas besoin de mettre $parent.back()
dans votre HTML.
Une autre petite chose à mentionner: même si nous utilisons replace: true
, Cliquer sur l'élément appelle toujours back()
. Cela fonctionne car "le processus de remplacement migre tous les attributs/classes de l'ancien élément vers le nouveau". - directive doc
Donc ng-click='back()' button='go back!'
est migré vers le premier div
dans le modèle de la directive.
Je suppose que vous devez utiliser la fonction de compilation dans ce cas.
angular.module('myApp').directive("button", function () {
return {
template: "<div><div another-directive></div>{{button}}</div>",
replace: true,
scope: true,
compile: function (tElement, tAttrs) {
// this is link function
return function (scope) {
scope.button = tAttrs.button;
};
}
};
});
Voici exemple jsfiddle .