繁体   English   中英

$ http承诺角度服务

[英]$http promise in angular service

我在角度服务中遇到了承诺的问题。 我有一个getArea方法的服务,它应该返回服务区域的名称。 该服务从API获取服务区域。 getArea获取服务区域时,它会找到所请求区域的名称,并应返回它。 但是,我的代码不起作用 - 我进入了无限循环。 我想我误解了如何使用承诺?

SupplierService:

var servicePromise;
var getServices = function(){
    if( !servicePromise ){
        servicePromise = $http.get('/api/services')
            .then(function(res){
                return res.data.data;
            });
    }
    return servicePromise;
};


var myService = {

    getServices : getServices,

    getArea : function(questionnaireId){
        getServices().then(function(services){
            // ...
            return "hello world";
        });
    }
};

return myService;

控制器:

$scope.supplierService = SupplierService;

视图:

<div>
    <b>Area:</b> {{ supplierService.getArea(r.questionnaireId) }}
</div

我希望视图显示“Area:hello world”,但进入无限循环。


更新1:我已将getServices添加为服务中的公共函数,并可以从控制器访问它,如下所示:

SupplierService.getServices().then(function(d){
    $scope.services = d;
});

因此我猜问题是在getArea方法中?


更新2:我受到了这个答案的启发https://stackoverflow.com/a/12513509/685352 我想缓存结果。


更新3:这是一个plunker 如果您尝试从视图中访问supplierService.getArea(100) - 浏览器将不会响应。

您的服务看起来应该更像这样:

var getServices = function(){
    var deferred = $q.deferred();
    $http.get('/api/services')
            .then(function(res){
                deferred.resolve(res.data)
            });
    return deferred.promise;
};

请注意,在创建延迟时,必须返回deferred.promise(实际的promise),然后在异步调用返回时,必须根据需要调用deferred.resolve或deferred.rejected(分别触发成功或错误函数)

轻微添加我有一个plunkr显示从服务到控制器的数据的几种方法,因为这是开发人员进入Angular的常见问题

http://plnkr.co/edit/ABQsAxz1bNi34ehmPRsF?p=info

这不是绝对的最佳实践,因为我试图尽可能简单,但基本上显示了三种不同的方式来“共享”您的数据,请记住这些方法中的一些依赖于angular.copy,这意味着您存储的服务的属性数据必须是Object或Array(原始类型不起作用,因为无法共享引用)。

这是一个重写,包括内联函数:

var myService = {
    var dataLoaded = false;
    var data = {}; //or = [];
    getServices : function(){
        var deferred = $q.defer();
        if( !dataLoaded ){
            $http.get('/api/services').then(function(res){
                angular.copy(res.data, myService.data);
                deferred.resolve(myService.data);
            }, function(err){
                deferred.reject("Something bad happened in the request");
            });
        }
        else
        {
            deferred.resolve(myService.data);
        }
        return deferred.promise;
    }
};

return myService;

为了解释,我使用$ q服务创建了一个新的承诺,您需要将其注入服务功能。 这允许我使用我已经拥有的数据来解决该承诺,或者调用该服务并解析该数据,但在这两种情况下使用它时,假设您将获得一个承诺,因此处理异步操作。 如果要加载多个数据集,则可以使用对象来存储标志而不是单个布尔值。

我想如果你返回$ http回调?

//$http.get('/someUrl').success(successCallback);


var getServices = function(){
    return $http.get('/api/services');

};

getServices.success(function(services){
// ...
           return "hello world";
        });
   }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM