TL; DR
1) Lorsque vous utilisez une usine, vous créez un objet, lui ajoutez des propriétés, puis retournez ce même objet. Lorsque vous transmettez cette usine à votre contrôleur, ces propriétés sur l'objet seront désormais disponibles dans ce contrôleur via votre usine.
app.controller('myFactoryCtrl', function($scope, myFactory){
$scope.artist = myFactory.getArtist();
});
app.factory('myFactory', function(){
var _artist = 'Shakira';
var service = {};
service.getArtist = function(){
return _artist;
}
return service;
});
2) Lorsque vous utilisez le service , Angular l'instancie en arrière-plan avec le «nouveau» mot clé. Pour cette raison, vous ajouterez des propriétés à «ceci» et le service renverra «ceci». Lorsque vous transmettez le service à votre contrôleur, ces propriétés sur «ceci» seront désormais disponibles sur ce contrôleur via votre service.
app.controller('myServiceCtrl', function($scope, myService){
$scope.artist = myService.getArtist();
});
app.service('myService', function(){
var _artist = 'Nelly';
this.getArtist = function(){
return _artist;
}
});
Non TL; DR
1) Les
usines d' usine sont le moyen le plus utilisé pour créer et configurer un service. Il n'y a vraiment pas beaucoup plus que ce que le TL; DR a dit. Il vous suffit de créer un objet, d'y ajouter des propriétés, puis de renvoyer ce même objet. Ensuite, lorsque vous passez l'usine dans votre contrôleur, ces propriétés sur l'objet seront désormais disponibles dans ce contrôleur via votre usine. Un exemple plus détaillé est présenté ci-dessous.
app.factory('myFactory', function(){
var service = {};
return service;
});
Maintenant, quelles que soient les propriétés que nous attachons au «service», nous serons disponibles lorsque nous passerons «myFactory» dans notre contrôleur.
Ajoutons maintenant quelques variables «privées» à notre fonction de rappel. Celles-ci ne seront pas directement accessibles depuis le contrôleur, mais nous finirons par mettre en place des méthodes getter / setter sur 'service' pour pouvoir modifier ces variables 'privées' si nécessaire.
app.factory('myFactory', function($http, $q){
var service = {};
var baseUrl = 'https://itunes.apple.com/search?term=';
var _artist = '';
var _finalUrl = '';
var makeUrl = function(){
_artist = _artist.split(' ').join('+');
_finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK';
return _finalUrl
}
return service;
});
Ici, vous remarquerez que nous n'attachons pas ces variables / fonctions au «service». Nous les créons simplement pour les utiliser ou les modifier ultérieurement.
- baseUrl est l'URL de base requise par l'API iTunes
- _artist est l'artiste que nous souhaitons rechercher
- _finalUrl est l'URL finale et entièrement construite vers laquelle nous ferons l'appel à iTunes makeUrl est une fonction qui créera et renverra notre URL conviviale iTunes.
Maintenant que nos variables et fonctions auxiliaires / privées sont en place, ajoutons quelques propriétés à l'objet «service». Quoi que nous mettions sur «service», nous serons en mesure d'utiliser directement le contrôleur dans lequel nous passerons «myFactory».
Nous allons créer des méthodes setArtist et getArtist qui renvoient ou définissent simplement l'artiste. Nous allons également créer une méthode qui appellera l'API iTunes avec notre URL créée. Cette méthode va retourner une promesse qui se réalisera une fois que les données seront revenues de l'API iTunes. Si vous n'avez pas beaucoup d'expérience dans l'utilisation des promesses dans Angular, je vous recommande fortement de les approfondir.
Ci-dessous, setArtist accepte un artiste et vous permet de définir l'artiste. getArtist renvoie l'artiste callItunes appelle d'abord makeUrl () afin de construire l'URL que nous utiliserons avec notre requête $ http. Ensuite, il configure un objet de promesse, fait une demande $ http avec notre URL finale, puis parce que $ http renvoie une promesse, nous sommes en mesure d'appeler .success ou .error après notre demande. Nous résolvons ensuite notre promesse avec les données iTunes, ou nous la rejetons avec un message disant «Il y a eu une erreur».
app.factory('myFactory', function($http, $q){
var service = {};
var baseUrl = 'https://itunes.apple.com/search?term=';
var _artist = '';
var _finalUrl = '';
var makeUrl = function(){
_artist = _artist.split(' ').join('+');
_finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
return _finalUrl;
}
service.setArtist = function(artist){
_artist = artist;
}
service.getArtist = function(){
return _artist;
}
service.callItunes = function(){
makeUrl();
var deferred = $q.defer();
$http({
method: 'JSONP',
url: _finalUrl
}).success(function(data){
deferred.resolve(data);
}).error(function(){
deferred.reject('There was an error')
})
return deferred.promise;
}
return service;
});
Maintenant, notre usine est terminée. Nous pouvons désormais injecter «myFactory» dans n'importe quel contrôleur et nous pourrons ensuite appeler nos méthodes que nous avons attachées à notre objet de service (setArtist, getArtist et callItunes).
app.controller('myFactoryCtrl', function($scope, myFactory){
$scope.data = {};
$scope.updateArtist = function(){
myFactory.setArtist($scope.data.artist);
};
$scope.submitArtist = function(){
myFactory.callItunes()
.then(function(data){
$scope.data.artistData = data;
}, function(data){
alert(data);
})
}
});
Dans le contrôleur ci-dessus, nous injectons dans le service «myFactory». Nous définissons ensuite des propriétés sur notre objet $ scope qui proviennent de données de «myFactory». Le seul code délicat ci-dessus est si vous n'avez jamais traité de promesses auparavant. Parce que callItunes renvoie une promesse, nous sommes en mesure d'utiliser la méthode .then () et de définir $ scope.data.artistData uniquement une fois que notre promesse est remplie avec les données iTunes. Vous remarquerez que notre contrôleur est très «mince». Toutes nos données logiques et persistantes se trouvent dans notre service, pas dans notre contrôleur.
2) Service
La chose la plus importante à savoir lors de la création d'un service est peut-être qu'il est instancié avec le «nouveau» mot clé. Pour vous, gourous de JavaScript, cela devrait vous donner une grande idée de la nature du code. Pour ceux d'entre vous qui ont peu d'expérience en JavaScript ou pour ceux qui ne connaissent pas trop ce que fait le `` nouveau '' mot clé, passons en revue quelques principes fondamentaux de JavaScript qui nous aideront éventuellement à comprendre la nature d'un service.
Pour vraiment voir les changements qui se produisent lorsque vous appelez une fonction avec le mot-clé `` nouveau '', créons une fonction et appelez-la avec le mot clé `` nouveau '', puis montrons ce que fait l'interpréteur lorsqu'il voit le mot clé `` nouveau ''. Les résultats finaux seront les mêmes.
Créons d'abord notre constructeur.
var Person = function(name, age){
this.name = name;
this.age = age;
}
Il s'agit d'une fonction constructeur JavaScript typique. Désormais, chaque fois que nous invoquerons la fonction Person à l'aide du mot-clé 'new', 'this' sera lié à l'objet nouvellement créé.
Ajoutons maintenant une méthode sur le prototype de notre Person afin qu'elle soit disponible sur chaque instance de notre 'classe' Person.
Person.prototype.sayName = function(){
alert('My name is ' + this.name);
}
Maintenant, comme nous avons placé la fonction sayName sur le prototype, chaque instance de Person pourra appeler la fonction sayName afin d'alerter le nom de cette instance.
Maintenant que nous avons notre fonction constructeur Person et notre fonction sayName sur son prototype, créons en fait une instance de Person puis appelons la fonction sayName.
var tyler = new Person('Tyler', 23);
tyler.sayName(); //alerts 'My name is Tyler'
Donc, tous ensemble, le code pour créer un constructeur Person, ajouter une fonction à son prototype, créer une instance Person, puis appeler la fonction sur son prototype ressemble à ceci.
var Person = function(name, age){
this.name = name;
this.age = age;
}
Person.prototype.sayName = function(){
alert('My name is ' + this.name);
}
var tyler = new Person('Tyler', 23);
tyler.sayName(); //alerts 'My name is Tyler'
Voyons maintenant ce qui se passe réellement lorsque vous utilisez le «nouveau» mot clé en JavaScript. La première chose que vous devriez remarquer est qu'après avoir utilisé 'new' dans notre exemple, nous pouvons appeler une méthode (sayName) sur 'tyler' comme si c'était un objet - c'est parce que c'est le cas. Donc, tout d'abord, nous savons que notre constructeur Person retourne un objet, que nous puissions le voir dans le code ou non. Deuxièmement, nous savons que notre fonction sayName étant située sur le prototype et non directement sur l'instance Person, l'objet renvoyé par la fonction Person doit être délégué à son prototype en cas d'échec des recherches. En termes plus simples, lorsque nous appelons tyler.sayName (), l'interpréteur dit «OK, je vais regarder l'objet 'tyler' que nous venons de créer, localiser la fonction sayName, puis l'appeler. Attendez une minute, je ne le vois pas ici - tout ce que je vois c'est le nom et l'âge, permettez-moi de vérifier le prototype. Ouais, on dirait que c'est sur le prototype, permettez-moi de l'appeler. ”.
Vous trouverez ci-dessous un code permettant de savoir ce que le «nouveau» mot clé fait réellement en JavaScript. Il s'agit essentiellement d'un exemple de code du paragraphe ci-dessus. J'ai mis la «vue interprète» ou la façon dont l'interprète voit le code à l'intérieur des notes.
var Person = function(name, age){
//The line below this creates an obj object that will delegate to the person's prototype on failed lookups.
//var obj = Object.create(Person.prototype);
//The line directly below this sets 'this' to the newly created object
//this = obj;
this.name = name;
this.age = age;
//return this;
}
Ayant maintenant cette connaissance de ce que le «nouveau» mot clé fait vraiment en JavaScript, la création d'un service en angulaire devrait être plus facile à comprendre.
La chose la plus importante à comprendre lors de la création d'un service est de savoir que les services sont instanciés avec le «nouveau» mot clé. En combinant ces connaissances avec nos exemples ci-dessus, vous devez maintenant reconnaître que vous attacherez vos propriétés et méthodes directement à «ceci» qui sera ensuite renvoyé par le service lui-même. Jetons un coup d'oeil à cela en action.
Contrairement à ce que nous avons fait à l'origine avec l'exemple Factory, nous n'avons pas besoin de créer un objet puis de le renvoyer car, comme mentionné plusieurs fois auparavant, nous avons utilisé le mot-clé 'new' pour que l'interpréteur crée cet objet, le déléguer à c'est un prototype, puis retournez-le sans que nous ayons à faire le travail.
Tout d'abord, créons notre fonction «privée» et d'assistance. Cela devrait sembler très familier puisque nous avons fait exactement la même chose avec notre usine. Je ne vais pas expliquer ce que fait chaque ligne ici parce que je l'ai fait dans l'exemple d'usine, si vous êtes confus, relisez l'exemple d'usine.
app.service('myService', function($http, $q){
var baseUrl = 'https://itunes.apple.com/search?term=';
var _artist = '';
var _finalUrl = '';
var makeUrl = function(){
_artist = _artist.split(' ').join('+');
_finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
return _finalUrl;
}
});
Maintenant, nous allons attacher toutes nos méthodes qui seront disponibles dans notre contrôleur à «ceci».
app.service('myService', function($http, $q){
var baseUrl = 'https://itunes.apple.com/search?term=';
var _artist = '';
var _finalUrl = '';
var makeUrl = function(){
_artist = _artist.split(' ').join('+');
_finalUrl = baseUrl + _artist + '&callback=JSON_CALLBACK'
return _finalUrl;
}
this.setArtist = function(artist){
_artist = artist;
}
this.getArtist = function(){
return _artist;
}
this.callItunes = function(){
makeUrl();
var deferred = $q.defer();
$http({
method: 'JSONP',
url: _finalUrl
}).success(function(data){
deferred.resolve(data);
}).error(function(){
deferred.reject('There was an error')
})
return deferred.promise;
}
});
Maintenant, tout comme dans notre usine, setArtist, getArtist et callItunes seront disponibles dans le contrôleur dans lequel nous transmettons myService. Voici le contrôleur myService (qui est presque exactement le même que notre contrôleur d'usine).
app.controller('myServiceCtrl', function($scope, myService){
$scope.data = {};
$scope.updateArtist = function(){
myService.setArtist($scope.data.artist);
};
$scope.submitArtist = function(){
myService.callItunes()
.then(function(data){
$scope.data.artistData = data;
}, function(data){
alert(data);
})
}
});
Comme je l'ai mentionné précédemment, une fois que vous comprenez vraiment ce que le «nouveau» fait, les services sont presque identiques aux usines d'Angular.