如何在AngularJS的工厂函数中使用$http.get()方法返回数据

13

我遇到了很多问题,但我似乎在SO或Google上找不到任何有助于我发现我的错误的帮助。

<!DOCTYPE html>
<html data-ng-app="testApp">
   <head>
      <title></title>
   </head>
   <body>
      <div data-ng-controller="myController">
         {{test}}<br/>
         {{test2}}<br/>
         {{test3}}
         <ul>
            <li data-ng-repeat="member in members">{{ member.firstname}}</li>
         </ul>
      </div>
      <script type="text/javascript" src="angular.min.js"></script>
      <script type="text/javascript">
         angular.module('testApp', ['memberFactory']);

         angular.module('testApp',[])
         .factory('memberFactory', function($http){

            var obj = {};
            obj.data = "abcd";
            obj.getResponse = function(){
                var temp = {};
                $http.get('hello.php').success(function(data){
                        alert(data);
                        temp =data;

                });

                return "some return value";
            }

            return obj
         });

         function myController($scope, memberFactory){ 
            $scope.test= "testString";
            $scope.test2= memberFactory.data;
            $scope.test3= memberFactory.getResponse();

         }
      </script>
   </body>
</html>

return "some return value";可以正常工作,但是当我尝试返回temp时,它是null。我尝试了各种方法,但似乎无法在$http.get()函数内部设置temp值。

这可能是一些简单的问题(或者是我的愚蠢错误/错误的方法)。任何建议将不胜感激。


你正在使用Angular 1.0.1版本,这将在1.3版本中出现问题。 - Fayyaz Ali
3个回答

24

使用defer:

obj.getResponse = function(){                 
    var temp = {};
    var defer = $q.defer();
    $http.get('hello.php').success(function(data){
            alert(data);
            temp =data;
            defer.resolve(data);

    });
    return defer.promise;
}

2
$q是什么?我得到了未定义的错误。这是另一个库吗? - jonnie
2
它必须以与$http相同的方式注入。这是承诺/延迟模式的AngularJS实现。 - Steve Klösters
1
是的。尝试按照@Matt Cooper的建议返回承诺。 - AlwaysALearner
1
冗余使用 $q。$http 返回一个 promise 对象。 obj.getResponse = function(){ var temp = {}; return $http.get('hello.php').success(function(data){ alert(data); temp =data; }); } - Brian Vanderbusch
@BrianVanderbusch 你如何解决延迟的 $http 返回? - Marcelo Mason
显示剩余5条评论

14

这里发生的情况是$http.get的异步特性造成的。当您运行$http.get时,它不会按顺序运行,而是“分支出”并与其余代码一起运行。这是为了适应服务器延迟。

以下是一个糟糕的示意图。

.getResponse Called                Return Temp.
|-------------------|--------------|
                    |---------------------------------|
                    $http.get ~Waiting for Server~    Temp assigned to data.

你能看到 Temp 在被赋值之前就被返回了吗?

谢天谢地,你可以使用 Angular 所谓的 promise,这是一个变量,你可以从函数中返回它,稍后得到“解决”。你可以像这样实例化一个 promise。

var myPromise = $q.defer();
您可以通过使用赋值语句为其分配值。
myPromise.resolve(data);
你可以在函数中正常地返回承诺,即可以稍后再次使用该承诺。例如:
return myPromise.promise

当然,要实现这一切,您需要使用$q库,并将其包含在函数参数中。


哎呀,我在发布之前没有看到Codezilla的答案,他们的想法是正确的。不过我会把这个留下来作为解释。 - Matt Cooper
感谢您的解释,不幸的是我现在只得到了 {"promise":{}} - jonnie
我已经解决了,我只需要调用 mypromise.$apply()。谢谢。 - jonnie
很好,我不会想到你必须要使用 $apply(),但我设法在这个 plunk(http://plnkr.co/edit/gUqz1Q0jUfXhkAJThTaK)上运行它了。祝你好运! - Matt Cooper
抱歉。您在哪里以及如何使用$apply?我正在尝试理解这个promise,但是... - Федор Усаков
显示剩余3条评论

0
//in  $httpProvider.interceptors    
if (typeof response.data === 'string') {
   return response;
}
else {
  return response.data;
}

你能否解释一下你在回答中具体在做什么?这将有助于理解。仅仅编写代码并不能清晰地表达。 - UDID

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接