2014-08-29 116 views
1

我正試圖調用多個$ http請求在一個工廠,我正在使用數據清除多個輸入並設置默認選擇。我想在一旦完成所有這三個操作來調用實際的表單數據(如果有的話,有時候不會有這種情況下它不會執行任何操作)來覆蓋默認設置的話,我們就會調用一個承諾。

所以這是我嘗試在這一點 -

工廠 我成立了一個工廠調用所有3個輸入和它們的默認值(我被送到他們的個人,我不能改變現在這個)。它看起來像這樣:

.factory("getDefaults", function() { 

return { 
    instructions: function() { 
     $http({ 
     method: "GET", 
     url: "/getStringDropdown/materials" 
    }) 
    .success(function(data, status, headers, config){ 
     $scope.instructions.materials = data.text; 
    }); 

    $http({ 
     method: "GET", 
     url: "/getStringDropdown/reinforce" 
    }) 
    .success(function(data, status, headers, config){ 
     $scope.reinforce = data.options; 
     $scope.instructions.reinforce = $scope.reinforce[data.default]; 
    }); 

    $http({ 
     method: "GET", 
     url: "/getStringDropdown/procedure" 
    }) 
    .success(function(data, status, headers, config){ 
     $scope.procedures = data.options; 
     $scope.instructions.procedures = $scope.procedures[data.default]; 
    }); 
    //return data here? 

    } 
    }; 

}) 

我在這裏的問題是 - 我必須在這裏返回數據?我也可以在這裏定義正在使用的範圍(與實際控制器中的相同)。我很確定這是錯誤的,但我不能找到一個很好的例子來說明如何正確地構建這樣的東西。

在控制器上的電話

所以我控制我的思想是那麼我會嘗試這樣的事情 -

getDefaults.instructions().then(function(){ 
      //possible return data here 
      //AFTER data is flushed out call farm data 

    $http({ 
     method: "GET", 
     url: "/getSavedFormData/formID" 
    }) 
    .success(function(data, status, headers, config){ 
     $scope.instructions.materials= data.materials; 
     $scope.instructions.procedures = $scope.procedures[data.procedure]; 
     $scope.instructions.reinforce = $scope.reinfoce[data.reinforcement]; 
    }); 

     }); 

那麼大圖片 - 我試圖讓這3個呼叫運行和填充,然後第二個。我不確定什麼可能或者不可能是最好的方法,工廠似乎是有意義的,因爲當他們全部完成時,試圖將3個呼叫合併到1個地方並承諾承諾。我想我需要返回數據,但是如果我可以在工廠中定義控制器的範圍,那將是相當不錯的。我仍然以角度得到我的方位,所以任何/所有的指導將非常感激。謝謝閱讀!!

+1

您是否嘗試過使用$ q.all() ? (像這裏:http://fdietz.github.io/recipes-with-angular-js/consuming-external-services/deferred-and-promise.html) – 2014-08-29 14:47:00

回答

3

您的服務並不知道你的$範圍的開箱即用的,也不是你可能希望它是作爲服務的全部意義在於協助的模塊化你代碼。

你可能想要做的是實際返回服務中的$ http promise,以便你的.success()回調實際上可以通過閉包(在控制器內)在$ scope上設置模型。

所以,你的工廠會更喜歡這樣的:

.factory("getDefaults", function() { 
    return { 
    instructions: $http({ method: "GET", url: "/getStringDropdown/materials" }) 
    } 
}); 

如果你真的認爲你再也不需要這些HTTP調用分開,你只關心時,他們所有的決心。你可以返回一個$ q。所有()承諾,將解決時,他們都決心:

.factory("getDefaults", function($http, $q) { 
    var promise1 = $http({ method: "GET", url: "/getStringDropdown/materials" }); 
    var promise2 = $http({ method: "GET", url: "/getStringDropdown/materials" }); 
    var promise3 = $http({ method: "GET", url: "/getStringDropdown/materials" }); 
    return { 
    data: $q.all([promise1,promise2,promise3]), 
    anotherCall: $http.get('/anothercallUrl') 
    } 
}); 

所以,現在從你的控制器,你可以只是做:

function myCtrl($scope,getDefaults){ 
    getDefaults.data.then(function(data){ 
    //access all three of your promises, their data, and set $scope models here 
    getDefaults.anotherCall.success(function(data){ 
     //or another http call 
    }); 
    }; 
} 

$ q.all文檔瀏覽:https://docs.angularjs.org/api/ng/service/$q

+0

這很好,謝謝你的幫助。有沒有辦法做另一個。然後我設置範圍然後調用最後的$ http? – ajmajmajma 2014-08-29 15:23:38

+0

當然,您可以再次發出另一個服務電話以返回另一個承諾。 getDefaults.anotherCall.success(功能(數據){})); – tommybananas 2014-08-29 15:25:05

+0

更新回答上面 – tommybananas 2014-08-29 15:27:09

1

使用在工廠範圍是不是一個好主意,我的建議不使用,有關多個HTTP調用,你應該使用這裏$q.all

例如fiddle

每個呼叫你應該創建延遲執行對象推到數組然後使用

$q.all(deferesArray).then(
     function(resp){ 
     // all requests are resolver , resp is array with resolved datas 
     } 
) 
1

您可能想要看看角的q $(https://docs.angularjs.org/api/ng/service/ $ q)

1.)創建前三個必須完成「第一個」的承諾

var deferred = $q.defer(); 
$http({ 
    method: "GET", 
    url: "/getStringDropdown/procedure" 
}) 
.success(function(data, status, headers, config){ 
    deferred.resolve(data); 
}); 
var promise1 = deferred.promise; 

2)使用q $的所有方法,然後調用「然後」以結果來執行你的邏輯的第二部分

q$.all([promise1, promise2, promise3]) 
.then(function(results) { 
$http({ 
    method: "GET", 
    url: "/getSavedFormData/formID" 
    }) 
    .success(function(data, status, headers, config){ 
    $scope.instructions.materials= data.materials; 
    $scope.instructions.procedures = $scope.procedures[data.procedure]; 
    $scope.instructions.reinforce = $scope.reinfoce[data.reinforcement]; 
}); 
}); 
+0

好吧,這看起來真棒。我在哪裏將數據放在前3個範圍內?例如 - 你用程序顯示的被調用的調用,我需要使用這些數據來做到這一點\t $ scope.procedures = data.options; $ scope.instructions.procedures = $ scope.procedures [data.default] ;.我會在那裏放置?謝謝!! – ajmajmajma 2014-08-29 15:16:16

+0

承諾接收到的「結果」參數包含結果對象數組,按照前3個承諾的傳遞順序排列。因此,$ scope.procedures = results [2] .options;例如... – alpinescrambler 2014-08-29 17:52:42