AngularJS $ HTTP调用服务,返回的数据解析,不承诺 [英] AngularJS $http call in a Service, return resolved data, not promises

查看:255
本文介绍了AngularJS $ HTTP调用服务,返回的数据解析,不承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道是否有可能使一个使用服务呼叫 $ HTTP 所以它直接返回数据,而不返回一个承诺?我曾尝试使用 $ Q 并推迟没有任何运气。

I want to know if it is possible to make a service call that uses $http so it returns data directly without returning a promise? I have tried to use the $q and defer without any luck.

下面是我的意思是:

我有一个服务:

angular.module('myModule').factor('myService', ['$http', '$q',
    function($http, $q) {

        // Public API
        return {
            myServiceCall: function() {
                return $http.get('/server/call');
            }
        };
    }
]);

这是我会怎么称呼它:

And this is how I would call it:

// My controller:
myService.myServiceCall().then(function(data) {
  $scope.data = data;
});

我想避免这种情况,而是希望有:

I want to avoid that and instead wish to have:

$scope.data = myService.myServiceCall();

我希望它在该行得到完全解决,这可能吗?

I want it to be fully resolved at that line, is it possible?

我已经试过$ Q的一些组合,推迟和'然后'的方法,但似乎无法得到它的权利,因为该方法会立即返回。

I have tried some combinations of $q, defer and 'then' methods but can't seem to get it right since the method returns immediately.

编辑:

如果你想知道为什么,最主要的原因是,我想简化控制器code,这是很容易与ngResource做那些调用在模板自动解决,所以我想避免需要做的整个'。然后'每次。

If you are wondering why, the main reason is that I wanted to simplify the controller code, this is easily done with ngResource as those calls are automatically resolved in templates, so I wanted to avoid the need to do the the whole '.then' everytime.

这并不是说我不喜欢的异步性,我们大部分的code的利用它,它只是在部分的情况下,有一个同步的方式是有帮助的。

It's not that I don't like the Async nature, most of our code leverages it, it's just in some cases, having a synchronous way is helpful.

我觉得现在的一些你所指出的那样,我会用$资源的足够近的解决方案。

I think for now as some of you have pointed out, I will use the $resource for a near enough solution.

推荐答案

有两种方式我能想到的做到这一点。首先是肯定比第二个好。

There are two ways I can think of to do this. The first is definitely better than the second.

您可以使用决心路由配置对象的属性来指定一个承诺必须得到解决,解决的值可以用于控制器的一个依赖的价值,所以,一旦你的控制器运行,该值立即可用。

You can use the resolve property of the route configuration object to specify that a promise must be resolved and the resolved value be used for the value of one of your controller dependencies, so that as soon as your controller runs, the value is immediately available.

举例来说,假设你有以下服务:

For example, say you have the following service:

app.service('things', ['$http', '$q', function ($http, $q) {
    var deferred = $q.defer();

    $http({
        method: 'GET',
        url: '/things',
        cache: true
    }).success(function (data) {
        deferred.resolve(data);
    }).error(function (msg) {
        deferred.reject(msg);
    });

    return deferred.promise;
}]);

然后,你可以定义你的路线是这样的:

Then you could define your route something like this:

$routeProvider.when('/things', {
    controller: ['$scope', 'thingsData', function ($scope, thingsData) {
        $scope.allThings = thingsData;
    }],
    resolve: {
        thingsData: ['things', function (things) {
            return things;
        }]
    }
});

解决关键对象对应于控制器的第二依赖关系的名字,所以尽管它返回一个承诺,这个承诺将控制器之前解决运行。

The key in the resolve object corresponds to the name of the second dependency for the controller, so even though it returns a promise, that promise will be resolved before the controller is run.

第二种方式,这是不是在所有的理想,并可能会咬你的屁股在某些时候,是让早期的数据的请求,例如当你的应用程序被初始化,然后居然得到数据以后,说需要3次点击获得来自主页的页面上。手指交叉,如果明星都一致,您的HTTP请求将不得不随后返回,你将不得不使用的数据。

The second way, which is not at all ideal, and will likely bite you on the bum at some point, is to make the request for the data early on, such as when your app is initialised, and then actually get the data later on, say on a page that requires 3 clicks to get to from the home page. Fingers crossed, if the stars have aligned, your http request will have returned by then and you will have the data to use.

angular.module('myModule').factory('myService', ['$http', '$q', function($http, $q) {
    var data = [];

    function fetch() {
        $http.get('/server/call').then(function (d) { data = d; });
    }

    // Public API
    return {
        fetchData: fetch,
        myServiceCall: function () {
            return data;
        }
    };
}]);

然后,在你的模块的运行功能,发出请求:

Then, in your module's run function, make the request:

angular.module('myModule').run(['myService', function (myService) {
    myService.fetchData();
});

然后,为保证应用程序启动后运行至少3秒一个页面控制器,你可以做你建议:

Then, in a controller for a page that is guaranteed to run at least 3 seconds after the app starts, you could do as you suggested:

 angular.module('myModule').controller('deepPageCtrl', ['$scope', 'myService', function ($scope, myService) {
      $scope.data = myService.myServiceCall();
      if (angular.isArray($scope.data) && $scope.data.length === 0) {
           panic("data isn't loaded yet");
      }
  }]);

奖金,同样不好第三种方式:同步Ajax请求

做的ricick建议,并使用同步AJAX请求可能与jQuery的阿贾克斯()方法。

这篇关于AngularJS $ HTTP调用服务,返回的数据解析,不承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆