web-dev-qa-db-fra.com

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

Si j’ai une fonction d’utilité foo que je veux pouvoir appeler de n’importe où à l’intérieur de ma déclaration ng-app. Est-il possible de le rendre globalement accessible dans la configuration de mon module ou dois-je l'ajouter à la portée de chaque contrôleur?

190
Ludwig Magnusson

Vous avez essentiellement deux options: le définir en tant que service ou le placer sur votre portée racine. Je suggérerais que vous en fassiez un service pour éviter de polluer la portée racine. 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 racine 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>

Ainsi, tous vos modèles peuvent appeler globalFoo() sans avoir à le transmettre au modèle à partir du contrôleur.

290
Anders Ekdahl

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>
53
ric

Bien que la première approche soit préconisée en tant que "approche angular semblable", je pense que cela ajoute des frais généraux.

Considérez si je veux utiliser cette fonction myservice.foo dans 10 contrôleurs différents. Je devrai spécifier cette dépendance 'myService' puis la propriété de portée $ scope.callFoo dans les dix d'entre elles. Ceci est simplement une répétition et viole en quelque sorte le principe DRY.

Tandis 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 que soit leur nombre.

44
Praym

AngularJs a " Services " et " Usines " uniquement pour des problèmes comme le vôtre. Ceux-ci 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, effectuer des calculs fonctions ou ce que vous voulez à l'intérieur Services et les utiliser dans les composants AngularJs en tant que 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 de services et d’usines AngularJs

4
Hazarapet Tunanyan

Je suis un peu plus récent que Angular, mais ce que j’ai trouvé utile de faire (et assez simple) c’est que j’ai créé un script global que je charge sur ma page avant le script local avec les variables globales auxquelles je dois accéder. sur toutes les pages quand même. Dans ce script, j'ai créé un objet appelé "globalFunctions" et ajouté les fonctions auxquelles j'ai besoin d'accéder globalement en tant que propriétés. par exemple. 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.

C’est un peu une solution de contournement et je ne suis pas sûr que cela vous aide, mais cela m’a certainement aidée car j’avais beaucoup de fonctions et c’était pénible de toutes les ajouter à chaque page.

0
Izzy