Les services AngularJS

Les services AngularJS permettent de partager du code dans toute votre application, grâce à ce que l’on appelle l’injection de dépendances.

AngularJS propose un grand nombre de services (et providers) prêts à l’emploi. Ceux-ci sont précédés du symbole $. En voici quelques exemples :

  • $timeout
  • $http
  • $compile

Si vous débutez sur AngularJS, et avant d’utiliser une méthode fournie par jQuery (au hasard), demandez vous toujours si le framework ne propose pas une solution. Ainsi, pour faire une requête Ajax, préférez utiliser $http plutôt que jQuery.ajax(). Dans le premier cas on reste dans le domaine d’AngularJS, dans le second, la view ne sera pas automatiquement mise à jour à la réception des données (pas instantanément en tout cas).

Les services AngularJS sont :

  • Lazily instantiated, c’est-à-dire instanciés que quand on en a besoin
  • Des singletons, c’est-à-dire qu’ils ne sont instanciés qu’une seule fois (et non une fois par importation)

Voici quelques exemples d’utilisation :

  • Récupérer des données via requêtes Ajax (au lieu de le faire un peu partout dans les contrôleurs)
  • Regrouper des fonctions « utilities » qui peuvent être utiles un peu partout dans votre application
  • Définir les paramètres de votre application (ex: mode développement/production …)

Exemple de création et d’utilisation d’un service

index.html

<!doctype html>
<html lang="fr" ng-app="myApp">
	<head>
		<meta charset="UTF-8">
		<title>Les services</title>
	</head>
<body>

	<div ng-controller="MainCtrl">
		<p>{{userData.firstName}}</p>
		<p>{{userData.userName}}</p>
		<p>{{userData.age}}</p>
	</div>

	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
	<script src="app.js"></script>
</body>
</html>

app.js

var app = angular.module("myApp", []);

/* Contrôleur principal
================================================== */

app.controller("MainCtrl", ["$scope", "userService",
	function($scope, userService) {
		$scope.userData = userService.getUserData();
	}
]);

/* Un premier service
================================================== */

app.service("userService", ["utilsService", "$timeout",
	function(utilsService, $timeout) {
		//Variable privée
		var userData = {
			firstName: "natasha",
			userName: "nat31",
			age: 25
		};

		//Getter pour la variable userData
		this.getUserData = function() {
			//Cette méthode fait appel à un autre service
			userData.firstName = utilsService.capitalize(userData.firstName);
			return userData;
		};

		//5 secondes après le chargement de la page, la valeur d'une propriété change dans le service.
		//La view est mise à jour automatiquement
		$timeout(function() {
			userData.userName = "NATNAT";
		}, 5000);
	}
]);

/* Un deuxième service
================================================== */

app.service("utilsService", [
	function() {
		this.capitalize = function(str) {
			//Credit: http://stackoverflow.com/a/1026087/962893
			return str.charAt(0).toUpperCase() + str.slice(1);
		};
	}
]);

 

Demo sur plnkr.coTélécharger la source

 

Explication du code

La view se contente d’afficher le contenu de la variable userData du contrôleur, rien de bien compliqué :

<div ng-controller="MainCtrl">
	<p>{{userData.firstName}}</p>
	<p>{{userData.userName}}</p>
	<p>{{userData.age}}</p>
</div>

La particularité de cette application est que le contrôleur fait appel à un service (userService) pour récupérer les données :

app.controller("MainCtrl", ["$scope", "userService",
	function($scope, userService) {
		$scope.userData = userService.getUserData();
	}
]);

Notez qu’il aurait été possible de donner à la view l’accès direct à userService, mais ça n’aurait pas été très élégant 🙁 :

$scope.userService = userService;

La déclaration d’un service est similaire à celle d’un contrôleur. Tout comme un contrôleur, il peut prendre en paramètre d’autres services, c’est ce que l’on appelle l’injection de dépendances. Cependant vous remarquerez qu’il n’y a pas de paramètre $scope, en effet un service n’est pas directement lié à la view.

app.service("userService", ["utilsService", "$timeout",
	function(utilsService, $timeout) {

	}
]);

Les données sont ici en dur, mais on pourrait les récupérer via une requête Ajax grâce au service $http :

//Variable privée
var userData = {
	firstName: "natasha",
	userName: "nat31",
	age: 25
};

Puisque que l’on a déclaré la fonction avec this, celle-ci est publique, elle est donc accessible depuis d’autres contrôleurs, services… à condition que le service soit injecté.

Remarquez également que ce service fait appel à un autre service pour mettre la première lettre du firstName en majuscule :

//Getter pour la variable userData
this.getUserData = function() {
	//Cette méthode fait appel à un autre service
	userData.firstName = utilsService.capitalize(userData.firstName);
	return userData;
};

Enfin, 5 secondes après le chargement de la page, la valeur d’une propriété change dans le service, mais puisque l’on est dans le domaine d’AngularJS, la view est mise à jour automatiquement. Le changement n’aurait pas été instantané si on avait utilisé setTimeout (de Javascript) :

$timeout(function() {
	userData.userName = 'NATNAT';
}, 5000);

Notez au passage que $timeout est aussi un service 😉

FAQ

Quelle est la différence entre service, factory, et provider ?

La différence technique, la voici http://jsfiddle.net/pkozlowski_opensource/PxdSP/14/. Lequel privilégier selon le contexte? Pour être parfaitement honnête avec vous, je ne sais pas. Le services me semblent convenir dans la plupart des cas, mais si quelqu’un à un contre-exemple (et il y en a forcément), partagez le dans les commentaires 🙂

L’utilisation intensive de services ne risque t’elle pas de ralentir mon application ?

A priori non. Comme je le disais en introduction, les services sont :

  • Instanciés seulement quand on en a besoin
  • Instanciés une seule fois

A voir aussi

Documentation officielle sur les services (anglais)

Share Button

13 thoughts on “Les services AngularJS

  1. Merci pour cet article.

    Personnellement j’utilise la factory dans la plupart des cas. Le niveau de complexité rajouté est très faible ( un simple return ) et elle a l’avantage de créer des méthodes privée ( tout ce qui n’est pas dans le return ne sera pas visible par l’appelant du service )

    • Jordi Maylin

      Si dans un service tu déclares une fonction comme ceci :
      function myFunction() { }
      et non comme ceci :
      this.myFunction = function() { }
      elle sera aussi privée, non? =)

  2. Jc

    Bonjour,
    [code]this.myFunction = function() { }[/code] n’est pas une fonction privée mais privilégiée. En tant que telle est est donc accessible de l’extérieur et par les méthodes publiques, et permet d’accéder aux propriétés et méthodes privées de la classe à laquelle elle appartient. Donc attention les deux écritures ne sont pas équivalentes.

    • Jordi Maylin

      Je me suis peut-être mal exprimé. Je disais que :
      function myFunction() { } était privée
      this.myFunction = function() { } était publique

  3. Merci pour l’article !

    Je débute sur AngularJS et tes tutos m’aident bien 😉

  4. meziane

    Bonjour,
    Je viens depuis seulement quelques jours d’aborder Angularjs, je ne suis pas développeur mais je connais pas mal de langages de programmation que j’utilise parfois dans mes activités perso.
    Et depuis que Google m’a emmené sur votre site, j’ai constaté la clarté de vos articles, qui m’ont aidé à vite commencer la pratique avec Angularjs.
    De tout mon cœur.. vraiment merci

    • Jordi Maylin

      Merci, ça fait plaisir 🙂

  5. Bertrand

    Merci pour ces tutos courts et très didactiques.
    Je pense avoir remarqué une erreur dans « Explication du code » lorsque vous proposez la solution « AJAX ».
    Dans le code qui suit, cela ne ressemble pas à une requête AJAX, c’est le même code que plus haut.
    Bravo en tout cas

    • Jordi Maylin

      Bonjour Bertrand, merci pour ton commentaire.
      Ce que j’ai voulu dire, c’est que dans l’exemple les données sont en dur, mais on aurait très bien pu les récupérer grâce à une requête AJAX (pas présent dans l’exemple).

  6. Skyward

    Bonjour,
    Tout d’abord merci pour ces tuto’s très clair et bien explicite. Je m’en sers pour un « homework » dans le cadre d’une candidature de stage de fin d’études où l’entreprise utilise justement de l’AngularJS. Je suis certes pointilleux mais une petite coquille est glissée : « la valeur d’unE propriété change dans le service ».
    Bravo en tout cas pour ton travail !

    • Jordi Maylin

      Merci Skyward. C’est corrigé

  7. alexandre

    Bonjour Jordi,

    Je te félicite pour la clarté de tes tutoriels, étant débutant + cela m’aide grandement.

    Aurais tu des conseils de toute sorte pour m’aider, que ce soit sur des astuces, la clarté du code et autre..

    Merci d’avance et bonne journée 🙂

    • Jordi Maylin

      Merci Alexandre,

      Une bonne manière de s’améliorer et de lire le code d’autres développeurs. Par exemple, tu peux jeter un oeil au framework Ionic (que j’utilise actuellement pour créer une appli iPhone ^^), un énorme projet open source qui s’appuie sur AngularJS https://github.com/driftyco/ionic

      Bonne chance 🙂

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>