2016-10-19 6 views
4

Ich bin verrückt geworden, etwas in Angular 1.3 zu arbeiten zu arbeiten, das möglicherweise nicht einmal möglich ist ... aber es scheint, dass es sein sollte. Grundsätzlich möchte ich einen Dienst schreiben, der nur einen berechneten Wert zurückgibt, kein Versprechen.Angular 1 Versprechen im Service

Ich habe einen Service, der eine $ http.get Anfrage macht und eine Zusage zurückgibt. Ich möchte das von einem anderen Dienst aufrufen, diese Daten abrufen, manipulieren und einen Wert zurückgeben. Ich möchte mich nicht damit auseinandersetzen müssen, sobald ich meinen Service angerufen habe. Mein Argument ist, dass ich gerne eine sharable-Funktion hätte, die ich aufrufen und einen tatsächlichen Wert erhalten kann, damit ich sie als Bedingung für etwas wie ng-show verwenden kann. Wie ich schon sagte, ich würde diese Funktion in den Controller schreiben und dann eine Variable mit den Daten aus dem Versprechen zuweisen, aber ich möchte das nicht in jedem einzelnen Controller schreiben, den ich brauche.

Beispiel:

app.factory('searchService', ['$http', function($http) { 
    return { 
    performSearch: function(searchString) { 
     return $http.get('http://asdf.com/search/' + searchString); 
    }, 
    getItemCount: function(itemName) { 
     var _this = this; 
     this.count = 0; 

     this.performSearch(itemName).then(
     function successCallback(resp) { 
      _this.count = resp.data.items.length; 
     }, 
     function errorCallback() { 
      // This section doesn't matter right now 
     }; 

     return this.count; 
    } 
    }; 
}]); 

So würde Ich mag nur in der Lage sein, dies von der Steuerung zu rufen und eine „5“ oder etwas zurückzubekommen. Oder noch besser, wenn man es von einer ng-Show wie "ng-show =" blahCtrl.getItemCount ('item_search_string') == 0 anruft. Auch hier habe ich mehrere Controller, die ich vielleicht brauchen würde, also würde ich lieber nicht duplizieren funktioniert überall nur um die Nummer zu extrahieren, die ich brauche

Das funktioniert bei mir einfach nicht ... mein Rückgabewert ist immer was immer ich anfänglich gesetzt habe.Ich habe eine Konsole eingebaut .log ein paar Orte und habe gesehen, dass (wie es scheint) This.Count zurückgegeben wird, bevor die Callback-Funktion ihren Wert festlegen kann. Egal was ich tue, ich bin unfähig, nur einen einzigen Wert von diesem Dienst zurückzugeben und es treibt mich Was mich mehr verwirrt ist, dass wenn ich diesen Code aus dem Controller heraus tun würde:

var _this = this; 
searchService.performSearch('asdf').then(
    function(data) { _this.searchResults.data; } 
); 

Es funktioniert gut und ich bekomme meine Versprechen Daten direkt in der Variable searchResults kein Problem. Es funktioniert aus irgendeinem Grund einfach nicht innerhalb des Dienstes.

Hoffentlich macht das Sinn, ich habe vielleicht ein bisschen gerattert oder war unklar. Jede Hilfe würde sehr geschätzt werden ... Ich habe ungefähr so ​​viel Zeit damit verbracht, dies zu erforschen und Trial-and-Error selbst zu verwenden, wie ich kann.

Danke!

+0

nehmen ein machen Schauen Sie sich die $ -Objektverwendung von Restangular an, ganz in der Nähe Ihres Wunsches ... –

+1

von Ihren Anforderungen, sieht aus wie Sie beabsichtigen performSearch, eine private Funktion zu sein, also warum retu rn es. Stattdessen gebe {getItemCount: function() {....}} zurück. Schreib die Funktion performSearch() {} kurz vor der Rückgabe {}. Dies ist eine private Funktion, wenn Sie sie auf diese Weise definieren und nicht zurückgeben. Wenn Sie die Funktion performSearch aufrufen möchten, müssen Sie sie verwenden.dann macht semantisch nur Sinn - "Call performSearch und DANN nach Outcome --DO- etwas. Es scheint, als ob Sie zwischen dem, was Sie wollen, Code-Qualität und Syntaxen stecken. – Mahesh

Antwort

0

Sie müssen $ q (https://docs.angularjs.org/api/ng/service/ $ q) verwenden. Ihre Funktion wird zurückgegeben, bevor das Versprechen erfüllt wird. Ihr getItemCount sollte wie folgt aussehen:

app.factory('searchService', ['$http', '$q', function($http, $q) { 
    return { 
    performSearch: function(searchString) { 
     return $http.get('http://asdf.com/search/' + searchString); 
    }, 
    getItemCount: function(itemName) { 
     var deferred = $q.defer(); 

     this.performSearch(itemName).then(
     function successCallback(resp) { 
      deferred.resolve(resp.data.items.length); 
     }, 
     function errorCallback(err) { 
      deferred.reject(err); 
     }; 

     return deferred.promise; 
    } 
    }; 
}]); 
+0

Das gibt immer noch ein Versprechen, richtig? Wenn ich das versuche, alles, was ich bekomme, ist {} returned.Wenn ich gerade zurückgebe, sehe ich es ist {"promise": {}} – user165222

+0

Dies gibt eine Zusage zurück, die zu 'resp.data.items.length' aufgelöst wird. Wenn Sie trösten möchten. Logge die Anzahl der Items ein, die du in die .then-Funktion schreiben solltest, zum Beispiel: 'getItemCount ('myitem'). dann (function (response) {console.log (response)});' –

+0

Ja, habe ich Das ist der springende Punkt hier ist, nur eine ganze Zahl zurückgeben, wenn ich diese Service-Funktion, nicht ANDERE Versprechen, dass ich wieder zu tun haben muss. Gibt es keine Möglichkeit, dies zu tun? Ich meine, wenn ich ein. dann hinzufügen () zu meiner Funktion performSearch() und lösche das Versprechen dort, dann, wenn ich in getItemCount bin, sollte ich nicht einfach ab sein sag performSearch(). then() und weise die Daten aus dem aufgelösten Versprechen einer Variablen zu, die ich zurückgeben kann? Aber so funktioniert es nie ... Es überspringt immer meine performSearch(). Dann und kehrt zurück, ohne zu warten. – user165222

1

Eine Lösung wie ich sehe.

dies in Controller

app.controller('ctrl', function ($scope, searchService) { 
    $scope.searchService = searchService; 
    searchService.getItemCount(); 
}); 

einmal ausdrückte und in allen Ansicht

{{ searchService.count }} 

Und ich denke, bekommen, ist es schlecht eine Anfrage für jede ng-if, ng-show usw.