La manière la plus simple de passer d’une variable de scope AngularJS de directive à contrôleur?

Quelle est la manière la plus simple de passer d’une variable de scope AngularJS de directive à contrôleur? Tous les exemples que j’ai vus semblent si complexes, n’y a-t-il pas un moyen d’accéder à un contrôleur à partir d’une directive et de définir l’une de ses variables de scope?

Edité le 08/14/25: Voici où je l’ai fourché.

Merci @anvarik.

Voici le JSFiddle . J’ai oublié où j’ai fourré ceci. Mais c’est un bon exemple qui vous montre la différence entre = et @

Parent Scope

// Update to see how parent scope interacts with component scope

Atsortingbute

get: {{isolatedAtsortingbuteFoo}}
set: // This does not update the parent scope.

Binding

get: {{isolatedBindingFoo}}
set: // This does update the parent scope.

Expression

// And this calls a function on the parent scope.
 var myModule = angular.module('myModule', []) .directive('myComponent', function () { return { ressortingct:'E', scope:{ /* NOTE: Normally I would set my atsortingbutes and bindings to be the same name but I wanted to delineate between parent and isolated scope. */ isolatedAtsortingbuteFoo:'@atsortingbuteFoo', isolatedBindingFoo:'=bindingFoo', isolatedExpressionFoo:'&' } }; }) .controller('MyCtrl', ['$scope', function ($scope) { $scope.foo = 'Hello!'; $scope.updateFoo = function (newFoo) { $scope.foo = newFoo; } }]); 

Attendez que l’angular ait évalué la variable

J’ai eu beaucoup de problèmes avec cela, et je ne pouvais pas le faire fonctionner même avec la variable définie avec "=" dans la scope. Voici trois solutions en fonction de votre situation.


Solution n ° 1


J’ai constaté que la variable n’a pas encore été évaluée par angular lorsqu’elle a été transmise à la directive. Cela signifie que vous pouvez y accéder et l’utiliser dans le modèle, mais pas dans la fonction de contrôleur de lien ou d’application, sauf si vous attendez qu’il soit évalué.

Si votre variable change ou est extraite par une requête, vous devez utiliser $observe ou $watch :

 app.directive('yourDirective', function () { return { ressortingct: 'A', // NB: no isolated scope!! link: function (scope, element, attrs) { // observe changes in atsortingbute - could also be scope.$watch attrs.$observe('yourDirective', function (value) { if (value) { console.log(value); // pass value to app controller scope.variable = value; } }); }, // the variable is available in directive controller, // and can be fetched as done in link function controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) { // observe changes in atsortingbute - could also be scope.$watch $attrs.$observe('yourDirective', function (value) { if (value) { console.log(value); // pass value to app controller $scope.variable = value; } }); } ] }; }) .controller('MyCtrl', ['$scope', function ($scope) { // variable passed to app controller $scope.$watch('variable', function (value) { if (value) { console.log(value); } }); }]); 

Et voici le HTML (rappelez-vous les crochets!):

 

Notez que vous ne devez pas définir la variable sur "=" dans la scope si vous utilisez la fonction $observe . En outre, j’ai trouvé qu’il transmettait des objects en tant que chaînes, donc si vous passez des objects, utilisez la solution n ° 2 ou scope.$watch(attrs.yourDirective, fn) (ou # 3 si votre variable ne change pas).


Solution n ° 2


Si votre variable est créée dans un autre contrôleur , par exemple , mais que vous devez simplement attendre qu’elle l’ait évaluée avant de l’envoyer au contrôleur de l’application, vous pouvez utiliser $timeout pour attendre que $apply soit exécuté. Nous devons également utiliser $emit pour l’envoyer au contrôleur d’application de scope parent (en raison de la scope isolée de la directive):

 app.directive('yourDirective', ['$timeout', function ($timeout) { return { ressortingct: 'A', // NB: isolated scope!! scope: { yourDirective: '=' }, link: function (scope, element, attrs) { // wait until after $apply $timeout(function(){ console.log(scope.yourDirective); // use scope.$emit to pass it to controller scope.$emit('notification', scope.yourDirective); }); }, // the variable is available in directive controller, // and can be fetched as done in link function controller: [ '$scope', function ($scope) { // wait until after $apply $timeout(function(){ console.log($scope.yourDirective); // use $scope.$emit to pass it to controller $scope.$emit('notification', scope.yourDirective); }); }] }; }]) .controller('MyCtrl', ['$scope', function ($scope) { // variable passed to app controller $scope.$on('notification', function (evt, value) { console.log(value); $scope.variable = value; }); }]); 

Et voici le HTML (pas de parenthèses!):

 

Solution n ° 3


Si votre variable ne change pas et que vous devez l’évaluer dans votre directive, vous pouvez utiliser la fonction $eval :

 app.directive('yourDirective', function () { return { ressortingct: 'A', // NB: no isolated scope!! link: function (scope, element, attrs) { // executes the expression on the current scope returning the result // and adds it to the scope scope.variable = scope.$eval(attrs.yourDirective); console.log(scope.variable); }, // the variable is available in directive controller, // and can be fetched as done in link function controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) { // executes the expression on the current scope returning the result // and adds it to the scope scope.variable = scope.$eval($attrs.yourDirective); console.log($scope.variable); } ] }; }) .controller('MyCtrl', ['$scope', function ($scope) { // variable passed to app controller $scope.$watch('variable', function (value) { if (value) { console.log(value); } }); }]); 

Et voici le HTML (rappelez-vous les crochets!):

 

Aussi, regardez cette réponse: https://stackoverflow.com/a/12372494/1008519

Référence pour le problème FOUC (flash de contenu non stylé): http://deansofer.com/posts/view/14/AngularJs-Tips-and-Tricks-UPDATED

Pour les intéressés: voici un article sur le cycle de vie angular