192 votes

Puis-je rendre une fonction disponible dans chaque contrôleur en angular ?

Si j'ai une fonction d'utilité foo que je veux pouvoir appeler de n'importe où dans mon ng-app déclaration. Y a-t-il un moyen de la rendre globalement accessible dans la configuration de mon module ou dois-je l'ajouter à la portée de chaque contrôleur ?

0 votes

Je ne suis pas sûr à 100%, mais il y a une chance que vous puissiez aussi le définir sur votre module comme ceci : module.value('myFunc', function(a){return a;}); et ensuite l'injecter par son nom dans vos contrôleurs. (Si l'on veut éviter de faire un service)

0 votes

Ce qui signifie que je dois l'ajouter manuellement à chaque contrôleur. $rootScope est la solution pour ce que je voulais faire il y a presque 2 ans =)

0 votes

OK. :) C'est juste que j'utilise plus souvent des directives avec une portée isolée que des contrôleurs simples et je dois tout injecter de toute façon. J'aime le style de code modulaire que cela procure. De plus, vous n'avez pas à vous occuper des scopes parents et vous n'avez pas à chercher d'où viennent les variables de votre scope :)

292voto

Anders Ekdahl Points 5678

Vous avez deux possibilités : soit vous le définissez comme un service, soit vous le placez sur votre Root Scope. Je vous suggère d'en faire un service pour éviter de polluer le Root scope. Vous créez un service et le rendez disponible dans votre contrôleur comme ceci :

<!doctype html>
<html ng-app="myApp">
<head>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.angularjs.org/1.1.2/angular.min.js"></script>
    <script type="text/javascript">
    var myApp = angular.module('myApp', []);

    myApp.factory('myService', function() {
        return {
            foo: function() {
                alert("I'm foo!");
            }
        };
    });

    myApp.controller('MainCtrl', ['$scope', 'myService', function($scope, myService) {
        $scope.callFoo = function() {
            myService.foo();
        }
    }]);
    </script>
</head>
<body ng-controller="MainCtrl">
    <button ng-click="callFoo()">Call foo</button>
</body>
</html>

Si ce n'est pas une option pour vous, vous pouvez l'ajouter à la portée Root comme ceci :

<!doctype html>
<html ng-app="myApp">
<head>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.angularjs.org/1.1.2/angular.min.js"></script>
    <script type="text/javascript">
    var myApp = angular.module('myApp', []);

    myApp.run(function($rootScope) {
        $rootScope.globalFoo = function() {
            alert("I'm global foo!");
        };
    });

    myApp.controller('MainCtrl', ['$scope', function($scope){

    }]);
    </script>
</head>
<body ng-controller="MainCtrl">
    <button ng-click="globalFoo()">Call global foo</button>
</body>
</html>

De cette façon, tous vos modèles peuvent appeler globalFoo() sans avoir à le passer au modèle depuis le contrôleur.

5 votes

Dans la première solution, que se passe-t-il s'il y a des tonnes de foo() fonctions ? Faire un $scope.callFoo() pour chacun d'entre eux est trop de travail. Comment puis-je "attacher" toutes les fonctions d'une bibliothèque dans la portée afin qu'elle puisse être utilisée dans le modèle ? J'ai une grande bibliothèque de conversion d'unités et je veux qu'elle soit disponible dans mon modèle.

3 votes

Ma question aussi. J'ai essayé et ça marche : on peut "attacher" en disant $scope.callFoo = myService.foo; au lieu de créer un nouveau wrapper à chaque endroit où vous souhaitez l'utiliser.

1 votes

Merci pour votre aide, je me demandais comment rendre disponible une fonction de changement de langue dans toute mon application et $rootScope a fait le travail. Je voulais garder le module de traduction à l'écart de l'application afin de pouvoir l'intégrer à d'autres applications.

54voto

rickerlr Points 11

Vous pouvez aussi les combiner, je suppose :

<!doctype html>
<html ng-app="myApp">
<head>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="http://code.angularjs.org/1.1.2/angular.min.js"></script>
    <script type="text/javascript">
        var myApp = angular.module('myApp', []);

        myApp.factory('myService', function() {
            return {
                foo: function() {
                    alert("I'm foo!");
                }
            };
        });

        myApp.run(function($rootScope, myService) {
            $rootScope.appData = myService;
        });

        myApp.controller('MainCtrl', ['$scope', function($scope){

        }]);

    </script>
</head>
<body ng-controller="MainCtrl">
    <button ng-click="appData.foo()">Call foo</button>
</body>
</html>

7 votes

Je pense que cela devrait être la réponse correcte, justifiée par la réponse de @Praym. Cela n'a pas de sens de spécifier une dépendance de service dans 10 contrôleurs différents.

0 votes

Le service peut-il inclure des méthodes/fonctions permettant de CRUDer des propriétés/variables dans l'interface utilisateur ? $rootScope ?

45voto

Praym Points 81

Bien que la première approche soit préconisée comme l'approche "angulaire", j'ai le sentiment que cela ajoute des frais généraux.

Imaginons que je veuille utiliser cette fonction myservice.foo dans 10 contrôleurs différents. Je devrai spécifier cette dépendance 'myService' et ensuite la propriété de portée $scope.callFoo dans les dix contrôleurs. Il s'agit simplement d'une répétition et, d'une certaine manière, d'une violation du principe DRY.

Alors que si j'utilise l'approche $rootScope, je spécifie cette fonction globale gobalFoo une seule fois et elle sera disponible dans tous mes futurs contrôleurs, quel qu'en soit le nombre.

5 votes

Il peut être utile que les contrôleurs "documentent" l'endroit où ils obtiennent cet appel de service global. Si vous deviez glisser l'un de vos contrôleurs dans une autre application, l'origine de cette fonction globale serait moins claire. Je reconnais cependant votre argument.

0 votes

Il ne doit être placé sur le scope que si vous avez besoin de l'appeler depuis la vue. Dans le contrôleur, vous pouvez l'appeler directement depuis le service.

10 votes

Il s'agit d'un commentaire et non d'une réponse

4voto

Hazarapet Tunanyan Points 1458

AngularJs a " Services " et " Usines "Ils sont utilisés pour avoir quelque chose de global. entre les contrôleurs, les directives, les autres services ou tout autre composant angularjs Vous pouvez définir des fonctions, stocker des données, créer des fonctions de calcul ou tout ce que vous voulez à l'intérieur. Services et les utiliser dans les composants AngularJs comme Global .comme

angular.module('MyModule', [...])
  .service('MyService', ['$http', function($http){
    return {
       users: [...],
       getUserFriends: function(userId){
          return $http({
            method: 'GET',
            url: '/api/user/friends/' + userId
          });
       }
       ....
    }
  }])

si vous avez besoin de plus

En savoir plus sur les raisons pour lesquelles nous avons besoin des services et des usines AngularJs

0voto

Izzy Points 301

Je suis un peu plus récent dans Angular mais ce que j'ai trouvé utile de faire (et assez simple) est que j'ai fait un script global que je charge sur ma page avant le script local avec des variables globales auxquelles je dois accéder sur toutes les pages de toute façon. Dans ce script, j'ai créé un objet appelé "globalFunctions" et j'ai ajouté les fonctions auxquelles j'ai besoin d'accéder globalement comme propriétés. par ex. globalFunctions.foo = myFunc(); . Ensuite, dans chaque script local, j'ai écrit $scope.globalFunctions = globalFunctions; et j'ai instantanément accès à toute fonction que j'ai ajoutée à l'objet globalFunctions dans le script global.

Il s'agit d'une solution de contournement et je ne suis pas sûr qu'elle vous soit utile, mais elle m'a été d'un grand secours car j'avais de nombreuses fonctions et il était très difficile de les ajouter à chaque page.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X