Je voudrais accéder à la portée d'une directive parent, mais je n'arrive pas à obtenir la bonne combinaison de paramètres. Est-ce possible et est-ce la bonne approche?
Je veux vraiment éviter de mettre quelque chose comme SOME_CONST (qui m'aiderait à faire des mises à jour DOM via le flux de contrôle) dans MyCtrl
<div ng-controller="MyCtrl">
<parent>
<child></child>
</parent>
</div>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.obj = {prop:'foo'};
}
myApp.directive('parent', function() {
return {
scope: true,
transclude: true,
restrict: 'EA',
template: '<div ng-transclude><h1>I\'m parent {{obj.prop}}<h1></div>',
link: function(scope, elem, attrs) {
scope.SOME_CONST = 'someConst';
}
}
});
myApp.directive('child', function() {
return {
restrict: 'EA',
template: '<h1>I\'m child.... I want to access my parent\'s stuff, but I can\'t. I can access MyCtrlScope though, see <b>{{obj.prop}}</b></h1> how can I access the <b>SOME_CONST</b> value in my parent\'s link function? is this even a good idea? {{SOME_CONST}}. I really don\'t want to put everything inside the MyCtrl',
}
});
Veuillez voir ceci ( violon
Merci
Avec transclude: true
et scope: true
, la directive parent
crée deux nouvelles étendues:
La portée 004 est le résultat de scope: true
, et la portée 005 est le résultat de transclude: true
. Étant donné que la directive child
ne crée pas de nouvelle étendue, elle utilise l'étendue transclue 005. Comme vous pouvez le voir sur le diagramme, il n'y a pas de chemin de l'étendue 005 à l'étendue 004 (sauf via la propriété privée $$ prevSibling, qui va dans la direction opposée de $$ nextSibling - mais ne les utilisez pas.)
La solution de @ joakimbl est probablement la meilleure ici, bien que je pense qu'il est plus courant de définir une API sur le contrôleur de la directive parent, plutôt que de définir des propriétés sur this
:
controller: function($scope) {
$scope.SOME_CONST = 'someConst';
this.getConst = function() {
return $scope.SOME_CONST;
}
}
Puis dans la directive child
:
link:function(scope,element,attrs,parentCtrl){
scope.SOME_CONST = parentCtrl.getConst();
},
C'est ainsi que les directives tabs
et pane
fonctionnent sur la page d'accueil d'Angular (exemple "Créer des composants").
Normalement, la façon dont vous accédez à une variable de portée parent dans une directive se fait via une liaison bidirectionnelle (scope:{model:'=model'}
- voir le angular sur les directives ) dans la configuration des directives), mais puisque vous utilisez la transclusion, ce n'est pas si simple. Si la directive enfant sera toujours un enfant de la directive parent, vous pouvez toutefois la configurer pour exiger le parent, puis accéder au contrôleur parent dans la fonction de liaison enfant:
myApp.directive('parent', function() {
return {
scope: true,
transclude: true,
restrict: 'EA',
template: '<div ng-transclude><h1>I\'m parent {{obj.prop}}<h1></div>',
controller: function($scope) {
$scope.SOME_CONST = 'someConst';
this.SOME_CONST = $scope.SOME_CONST;
}
}
});
myApp.directive('child', function() {
return {
restrict: 'EA',
require:'^parent',
scope:true,
link:function(scope,element,attrs,parentCtrl){
scope.SOME_CONST = parentCtrl.SOME_CONST;
},
template: '<h1>I\'m child.... I want to access my parent\'s stuff, but I can\'t. I can access MyCtrlScope though, see <b>{{obj.prop}}</b></h1> how can I access the <b>SOME_CONST</b> value in my parent\'s link function? is this even a good idea? {{SOME_CONST}}. I really don\'t want to put everything inside the MyCtrl',
}
});
Voir cette mise à jour: http://jsfiddle.net/uN2uv/
J'ai juste eu le même problème et je l'ai finalement résolu avec le angular;)
En bref: vous devez utiliser une directive contrôleur dans votre parent et exiger ce contrôleur dans votre enfant directive. De cette façon, vous pouvez obtenir vos propriétés parentales.
Voir https://docs.angularjs.org/guide/directive Chapitre: Création de directives qui communiquent
J'ai changé votre violon pour utiliser un contrôleur, maintenant vous pouvez accéder à votre constante: https://jsfiddle.net/bbrqdmt3/1/
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.obj = {prop:'foo'};
}
myApp.directive('parent', function() {
return {
scope: true,
transclude: true,
restrict: 'EA',
template: '<div ng-transclude><h1>I\'m parent {{obj.prop}}<h1></div>',
controller: function($scope) {
this.getConst= function() {
return 'someConst';
}
},
}
});
myApp.directive('child', function() {
return {
restrict: 'EA',
require : '^parent',
link: function(scope, element, attrs, ctrl) {
scope.value= ctrl.getConst();
},
template: '<h1>I\'m child.... I want to access my parent\'s stuff, but I can\'t. I can access MyCtrlScope though, see <b>{{obj.prop}}</b></h1> how can I access the <b>SOME_CONST</b> value in my parent\'s link function? is this even a good idea? {{value}}. I really don\'t want to put everything inside the MyCtrl',
}
});
Il y a une transclude fn dans les arguments du lien fn après le contrôleur.
myApp.directive('parent', function() {
return {
scope: true,
transclude: true,
restrict: 'EA',
template: '<div><h1>I'm a parent header.</h1></div>',
link: function (scope, el, attrs, ctrl, transclude) {
transclude(scope, function (clone, scope) {
element.append(clone); // <-- will transclude it's own scope
});
},
controller: function($scope) {
$scope.parent = {
binding: 'I\'m a parent binding'
};
}
}
});
myApp.directive('child', function() {
return {
restrict: 'EA',
require:'^parent',
scope:true,
link:function(scope,element,attrs,parentCtrl){
},
template: '<div>{{parent.binding}}</div>' // <-- has access to parent's scope
}
});