2015-02-08 2 views
5

Ich bin neu in angularjs. Mein Ziel ist sehr einfach. Ich möchte einen Ajax-Aufruf machen, um Daten zu erhalten, und wenn ich fertig bin, möchte ich einen zweiten Aufruf machen, um einen anderen Satz von Daten zu erhalten, der von Informationen in der ersten Menge abhängt.

Ich versuche, dies zu tun Verheißungsmechanismen verwenden, so dass ich Verkettung anstelle von verschachtelten Ajax-Aufrufe verwenden kann und die Fähigkeit, unabhängige Funktionen zu haben, die ich bei Bedarf verknüpfen kann.

Mein Code sieht ungefähr wie folgt:

var promiseGetWorkTypes = function ($q, $scope, $http) { 
 
\t console.log("promiseGetWorkTypes"); 
 

 
\t return $q(function (resolve, reject) { 
 
\t \t $http({ 
 
\t \t \t method: 'GET', 
 
\t \t \t url: '/WorkTypes' 
 
\t \t }).then(
 
\t \t \t function (payload) { 
 
\t \t \t \t console.log("Got workttypegroups") 
 
\t \t \t \t console.log(payload); 
 

 
\t \t \t \t $scope.WorkTypeGroups = payload.data; 
 

 
\t \t \t \t console.log("End of worktypegroups"); 
 
\t \t \t \t resolve(payload); 
 
\t \t \t }, 
 
\t \t \t function (payload) { 
 
\t \t \t \t reject(payload); 
 
\t \t \t }); 
 
\t }); 
 
}; 
 

 
var promiseGetRecentActivities = function ($q, $scope, $http) { 
 
\t console.log("promiseGetRecentActivities"); 
 

 
\t return $q(function (resolve, reject) { 
 
\t \t $http({ 
 
\t \t \t method: 'GET', 
 
\t \t \t url: '/RecentHistory' 
 
\t \t }).then(
 
\t \t \t function (payload) { 
 
\t \t \t \t $scope.RecentActivities = payload.data; 
 

 
\t \t \t \t resolve(payload); 
 
\t \t \t }, 
 
\t \t \t // data contains the response 
 
\t \t \t // status is the HTTP status 
 
\t \t \t // headers is the header getter function 
 
\t \t \t // config is the object that was used to create the HTTP request 
 
\t \t \t function (payload) { 
 
\t \t \t \t reject(payload); 
 
\t \t \t }); 
 
\t }); 
 
}; 
 

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

 
index 
 
.controller('EntitiesController', function ($scope, $http, $timeout, $q) { 
 
\t promiseGetWorkTypes($q, $http, $scope) 
 
\t \t .then(promiseGetRecentActivities($q, $http, $scope)); 
 
}

Allerdings, wenn ich an meine Debug-Konsole schauen, wie ich sehe, dass der Anruf auf "promiseGetRecentActivities" vor dem Aufruf beginnt die Ajax Handling ist bei "promiseGetWorkTypes" aufgetreten.

Was vermisse ich oder mache ich hier falsch?

+1

Verwenden Sie '$ q.all' http://jsfiddle.net/ThomasBurleson/QqKuk/ – underscore

+0

Nein, nicht' $ q.all() '. OP möchte die beiden Ajax Calls in Serie schalten. –

+3

http://stackoverflow.com/questions/23803743/what-is-the-sefered-antipattern-and-how-do-i-avoid-it –

Antwort

6

Wenn Sie

promiseGetWorkTypes($q, $http, $scope).then(promiseGetRecentActivities($q, $http, $scope)); 

schreiben die promiseGetActivites zu der Zeit genannt wird diese Zeile ausgewertet wird. Sie sollen den Aufruf der Lage sein, den Anruf zu promiseGetActivities in einer anderen Funktion zu wickeln zu verzögern, bis das erste Versprechen, die Anrufe zu bekommen gelöst hat nacheinander auszuführen:

promiseGetWorkTypes($q, $http, $scope).then(function() { 
    promiseGetRecentActivities($q, $http, $scope); 
}); 

Der Grund, etwas ist nicht mit dem zu tun, was passiert, innerhalb then, aber wegen Javascript-Syntax. Die folgende:

myFunc1(myFunc2()); 

gibt die Ergebnis MyFunc1myFunc2() des Aufrufs und nicht ein Verweis auf die myFunc2 Funktion. Logischerweise müsste also myFunc2 vor myFunc1 laufen. Wenn Sie

schrieb
myFunc1(myFunc2); 

dann myFunc1 einen Verweis auf myFunc2, empfangen und so myFunc1 liefe vor myFunc2 (und in der Tat wird myFunc2 nur, wenn irgendwo laufen innerhalb myFunc1 es Code, der es nennt).

Das Definieren einer Funktion inline/anonymous ändert dieses Verhalten nicht. Um ein Ergebnis einer anonymen Funktion an eine andere Funktion übergeben können Sie die folgenden Aktionen

myFunc1((function() { 
    return 'something'; 
})()); 

, die die anonyme Funktion zuerst evaluieren, wie der Rückgabewert wird 'something'-myFunc1 weitergegeben. Um einen Verweis auf eine anonyme Funktion übergeben Sie folgendes tun:

myFunc1(function() { 
    return 'something'; 
}); 

und dann wird es bis zu myFunc1 ob sie jemals die Funktion aufrufen, an sie übergeben.

es zurück zu Ihrer Frage bringen, Ihr Code:

promiseGetWorkTypes($q, $http, $scope).then(promiseGetRecentActivities($q, $http, $scope)); 

ist das Ergebnis der promiseGetRecentActivities($q, $http, $scope) zu then vorbei, so muss es laufen, bevor then ausgeführt wird, und so schon gar nicht für das Versprechen nicht warten, um von promiseGetWorkTypes gelöst werden. Was Sie scheinen zu wollen, ist es passieren eine Funktion, die, wenn sie aufgerufen wird, promiseGetRecentActivities($q, $http, $scope) läuft, das, was

ist
promiseGetWorkTypes($q, $http, $scope).then(function() { 
    promiseGetRecentActivities($q, $http, $scope); 
}); 

tut.

Als Nebennote, scheint es ein wenig ungewöhnlich/zu kompliziert $q zu vorbei, $http usw. um, um verschiedene Funktionen, aber ich denke, wahrscheinlich über den Rahmen dieser Frage durch Alternativen zu gehen.

+0

Wow! Das scheint zu funktionieren, aber ich kann nicht verstehen warum. Ich hätte gedacht, dass der ".then" -Aufruf beim Aufruf der Funktionsvariablen, die übergeben wurden, bis das vorherige Versprechen gelöst wurde. Und wenn es sofort "promiseGetRecentActivities" nennt, warum sollte es nicht sofort die anonyme Funktion nennen? Gibt es eine Art von Logik, die beim Aufruf von ".then" nach einer parameterlosen oder unbenannten Methode sucht? – dshockey

+0

@dshockey Ich habe mehr zu meiner Antwort hinzugefügt, um zu erklären, –

+0

Das macht alles Sinn und ich hätte erkennen sollen, dass ich das tat. Ich glaube, ich habe mich in Funktionen als erstklassige Objekte verirrt und nicht bemerkt, dass ich die Funktion aufgerufen und das Ergebnis weitergegeben habe, wie es in jeder anderen Sprache der Fall wäre. Danke, dass Sie das erklärt haben. Ich habe nur noch eine Frage: Warum erlaubt ".then" dann etwas anderes als eine Funktionsreferenz? Was würde es mit anderen Daten tun? Ich bin überrascht, dass ich keinen Laufzeitfehler beim Versuch, das Ergebnis meines Aufrufs an "promseGetRecentActivities" statt einer Funktionsreferenz zu übergeben, festgestellt habe. – dshockey