我正在使用angularjs 1.4.7中的$http
。
我需要将控制器与任何$http
请求分开。所以我创建了如下服务:
app.service('MyService', function($http, $q, $rootScope) {
this.getcustomers = function() {
var deferred = $q.defer();
$http({
method: 'GET',
url: 'http://call/to/rest/api'
}).then(function successCallback(response) {
deferred.resolve(response.data);
}, function errorCallback(response) {
deferred.reject(error);
});
return deferred.promise;
};
});
然后在我的控制器中,我按如下方式调用该服务:
app.controller('registerationCtrl', ['$scope', '$http', 'MyService', '$location', function($scope, $http, MyService, $location) {
$scope.custlst = [];
$scope.getcustomers = function() {
var x = MyService.getcustomers().then(function(data) {
$scope.custlst = data;
}, function(err) {
alert(err);
});
}
}]);
现在,以上操作无效,它现在定义了ReferenceError
错误,并指向服务中的errorCallback
函数。
问题1:脚本有什么问题?
问题2:使用$q
是否重要?请记住,服务器可能很慢。
感谢。
答案 0 :(得分:2)
实际上,您不需要使用$q
来创建承诺。 $http
已经为你做了,所以你可以这样做:
app.service('MyService', function($http) {
this.getcustomers = function() {
return $http.get({
method: 'GET',
url: 'http://call/to/rest/api'
});
};
});
然后,您可以轻松地将MyService.getcustomers
与.then()
链接起来,并按照以下方式处理响应:
MyService.getcustomers.then(
function(data) {
//do something with data
},
function(error) {
//do something with error
}
);
我认为你应该看一下this post我想更好地理解承诺的运作方式和行为。
编辑:更新已弃用的$http
来电。
答案 1 :(得分:1)
嗯,在AngularJS文档中:https://docs.angularjs.org/api/ng/service/$http
弃用通知 $ http旧版承诺方法成功与错误已被弃用。请改用标准方法。如果 $ httpProvider.useLegacyPromiseExtensions设置为false然后这些 方法将抛出$ http / legacy错误。
您不需要使用$ q承诺。
当您使用GET请求时,您可以使用快捷方式执行GET请求:$http.get();
。
所以,你可以尝试这样的事情:
MyService服务:只需要$http
服务。
app.service("MyService", ["$http", function ($http) {
this.getcustomers = function () {
return $http.get("http://call/to/rest/api");
};
}]);
上述服务允许您在任何控制器中使用该服务。因此,任何控制器都可以使用相同的数据执行其他操作。
registerationCtrl controller:您需要$scope
,MyService
和location
服务。
app.controller("registerationCtrl", ["$scope", "MyService", "$location", function ($scope, MyService, location) {
$scope.custlst = [];
$scope.getcustomers = function () {
MyService.getcustomers().then(function (response) {
$scope.custlst = response.data;
}, function (err) {
alert(err);
});
};
}]);
}]);
答案 2 :(得分:1)
正如我在评论中提到的,您看到的错误是由于error
变量未在errorCallback
函数中声明。
至于$q
- 不需要使用它,虽然你实现的方式仍然可行。为了使它更简单并遵循promises的意图(即它们允许异步代码镜像同步代码的代码组合),最好返回$http
(或{{1}的原始承诺。 }):
$http().then()
然后,客户端可以按预期使用:
this.getcustomers = function() {
return $http({
method: 'GET',
url: 'http://call/to/rest/api'
})
// pre-process the HTTP response and return the data
.then(function(response) {
return response.data;
})
// If needed, create a custom error to hide HTTP details from caller
// otherwise, don't include .catch - the original error will "bubble up"
.catch(function(error) {
return $q.reject({
msg: "something broke"
});
});
};