Die Einstellung: Ich möchte einen Dienst haben, dass mehrere Controller Daten abfragen können, die mit $ http abgerufen werden. Die ursprüngliche Lösung bestand darin, Versprechungen wie vorgeschlagen here zu verwenden.
Das Problem: Jedes Mal, wenn ein Controller den Dienst abfragt, gibt der Dienst ein $ http-Versprechen zurück, was zu mehreren Abfragen führt, die dieselben Daten immer und immer wieder von einem Remote-Server abrufen.
Eine Lösung: Die Servicefunktion gibt entweder Daten oder ein Versprechen wie unten zurück. Und es ist Aufgabe des Controllers, dies zu überprüfen und entsprechend zu handeln. So
app.factory('myService', function($http) {
var items = [];
var myService = {
getItems: function() {
// if items has content, return items; otherwise, return promise.
if (items.length > 0) {
return items;
} else {
var promise = $http.get('test.json').then(function (response) {
// fill up items with result, so next query just returns items.
for(var i=0;i<response.data.length;i++){
items.push(response.data[i]);
}
return items;
});
// Return the promise to the controller
return promise;
}
};
return myService;
});
, wenn ein Controller benötigt, dass die Daten, die Steuerung funktioniert nur so etwas wie diese:
app.controller('MainCtrl', function(myService,$scope) {
var promiseOrData = myService.async();
// Check whether result is a promise or data.
if (typeof promiseOrData.then === 'function'){
// It's a promise. Use then().
promiseOrData.then(function(data){
$scope.data = data;
});
} else {
// It's data.
$scope.data = data;
}
});
Die Frage ist also: Gibt es einen besseren Weg, dies zu tun? Bei vielen Controllern hätte diese Methode viel doppelten Code. Idealerweise fragen die Controller den Dienst direkt nach Daten ab.
Danke!
Nice work. Noch besser reduziert es die Menge an Code in der Steuerung benötigt. –
Irgendeine Möglichkeit, dies auf der Serviceseite DRY zu machen? Ich habe mehrere http-Endpunkte, an denen ich dies tun möchte und diesen Code für jeden Service/HTTP-Endpunkt zu wiederholen, würde außer Kontrolle geraten –
@KyleKochis, das einzige, was ich tun konnte, ist einen einzigen [HTTP Interceptor] zu erstellen (http://StackOverflow.com/a/11957760/215945) HTTP-Fehler für alle meine Dienste abzufangen, so dass der obige Code keinen Fehlerhandler mehr benötigt. –