web-dev-qa-db-fra.com

Convertir Angular HTTP.get en service

J'essaie de convertir un Angular HTTP.get fonction dans mon controllers.js vers un service dans services.js.

Les exemples que j'ai trouvés ont tous des façons conflictuelles de mettre en œuvre le service et leur choix de noms est déroutant. De plus, la documentation réelle angular pour les services utilise une syntaxe différente de celle de tous les exemples. Je sais que c'est super simple, mais aidez-moi ici.

J'ai app.js, controllers.js, services.js, filters.js.

app.js

angular.module('MyApp', []).
    config(['$routeProvider', function($routeProvider)
        {
            $routeProvider.
                when('/bookslist', {templateUrl: 'partials/bookslist.html', controller:             BooksListCtrl}).
                otherwise({redirectTo: '/bookslist'});
        }
    ]);

controllers.js

function BooksListCtrl($scope,$http) {
    $http.get('books.php?action=query').success(function(data) {
        $scope.books = data;
    });

    $scope.orderProp = 'author';
}
46
Brandon

Pensez en termes de modules et d'injection de dépendances.

Donc, disons que vous avez ces trois fichiers

<script src="controllers.js"></script>
<script src="services.js"></script>
<script src="app.js"></script>

Vous auriez besoin de trois modules

1. Module principal de l'application

angular.module('MyApp', ['controllers', 'services'])
  .config(['$routeProvider', function($routeProvider){
    $routeProvider
      .when('/bookslist', {
        templateUrl: 'partials/bookslist.html', 
        controller:  "BooksListCtrl"
      })
      .otherwise({redirectTo: '/bookslist'});
  }]);

Notez que les deux autres modules sont injectés dans le module principal, de sorte que leurs composants sont disponibles pour l'ensemble de l'application.

2. Module Contrôleurs

Actuellement, votre contrôleur est une fonction globale, vous voudrez peut-être l'ajouter dans un module de contrôleurs

angular.module('controllers',[])
  .controller('BooksListCtrl', ['$scope', 'Books', function($scope, Books){
    Books.get(function(data){
      $scope.books = data;
    });

    $scope.orderProp = 'author';
  }]);

Books est passé à la fonction contrôleur et est rendu disponible par le module services qui a été injecté dans le module d'application main.

3. Module Services

C'est là que vous définissez votre service Books.

angular.module('services', [])
  .factory('Books', ['$http', function($http){
    return{
      get: function(callback){
          $http.get('books.json').success(function(data) {
          // prepare data here
          callback(data);
        });
      }
    };
  }]);

Il existe plusieurs façons d'enregistrer des services.

  • service: passe une fonction constructeur (on peut l'appeler une classe) et retourne une instance de la classe.
  • fournisseur: le plus flexible et configurable car il vous donne accès aux fonctions que l'injecteur appelle lors de l'instanciation du service
  • sine: une fonction est invoquée par l'injecteur lors de l'instanciation du service.

Ma préférence en utilisant la fonction factory et en lui renvoyant simplement un objet. Dans l'exemple ci-dessus, nous renvoyons simplement un objet avec une fonction get à laquelle un rappel de réussite a été transmis. Vous pouvez également le modifier pour transmettre une fonction d'erreur.


Modifier En répondant à la demande de @ yair dans les commentaires, voici comment vous injecteriez un service dans une directive.

4. Module Directives

Je suis le schéma habituel, ajoutez d'abord le fichier js

<script src="directives.js"></script>

Ensuite, définissez un nouveau module et enregistrez des éléments, dans ce cas une directive

angular.module('directives',[])
  .directive('dir', ['Books', function(Books){
    return{
      restrict: 'E',
      template: "dir directive, service: {{name}}",
      link:function(scope, element, attrs){
        scope.name = Books.name;
      }
    };
  }]);

Injectez le module directive dans le module principal dans app.js.

angular.module('MyApp', ['controllers', 'services', 'directives']) 

Vous voudrez peut-être suivre une stratégie différente et injecter un module dans le module directives

Notez que la syntaxe annotation de dépendance en ligne est la même pour presque tout. La directive reçoit le même service Books.

Plunker mis à jour: http://plnkr.co/edit/mveUM6YJNKIQTbIpJHco?p=preview

121
jaime

Voici une implémentation du service après-vente au lieu du service d'usine mentionné ci-dessus. J'espère que ça aide.

app.js

angular.module('myApp', ['controllers', 'services'])
 .config(['$routeProvider', function($routeProvider){
    $routeProvider
      .when('/bookslist', {
        templateUrl: 'partials/bookslist.html', 
        controller:  "BooksListCtrl"
      })
      .otherwise({redirectTo: '/bookslist'});
  }]);

service.js

angular.module('services', [])
  .service('books', ['$http', function($http){
      this.getData = function(onSuccess,onError){
          $http.get('books.json').then(
              onSuccess,onError);
      }  
  }]);

controller.js

angular.module('controllers',[])
    .controller('BooksListCtrl', ['$scope', 'books', function($scope, books){
       $scope.submit = function(){

        $scope.books = books.getData($scope.onSuccess,$scope.onError);
       }
           $scope.onSuccess = function(data){
           console.log(data);
           $scope.bookName = data.data.bookname;
           }

           $scope.onError = function(error){
               console.log(error);
           }
  }]);
3