我正在尝试在工厂中调用多个$ http请求,我用它来清除多个输入数据并设置默认选择。我想在完成其中所有3个调用一个承诺后,调用真实表单数据(如果有的话,有时候不会在哪种情况下它将无效)来覆盖默认值。
所以这是我对此的尝试 -
工厂 我建立了一个工厂来调用所有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个调用合并到一个地方,并在完成后完成承诺。我想我需要返回数据,但如果我可以在工厂中定义控制器的范围,那将是非常好的。我仍然用棱角分明,所以任何/所有的指导都会非常感激。感谢您的阅读!!
答案 0 :(得分:3)
您的服务不了解您的$ scope开箱即用,您也不希望它是因为整个服务点都是为了协助您的代码的模块化。
您可能想要做的是实际从服务返回$ http保证,以便您的.success()回调实际上可以通过闭包(在控制器内)设置$ scope上的模型。
所以你的工厂会更像这样:
.factory("getDefaults", function() {
return {
instructions: $http({ method: "GET", url: "/getStringDropdown/materials" })
}
});
如果你真的认为你永远不会单独需要这些http电话,你只关心它们何时解决。你可以返回一个$ q.all()保证,它将在它们全部解决时解决:
.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
});
};
}
答案 1 :(得分:1)
在工厂中使用范围不是一个好主意,我的建议是不使用,关于多个http调用你应该使用$q.all
示例此处fiddle
对于每个调用,你应该创建deferred对象将其推入数组然后使用
$q.all(deferesArray).then(
function(resp){
// all requests are resolver , resp is array with resolved datas
}
)
答案 2 :(得分: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];
});
});