我最近发布了一篇关于我在SO面临的问题的详细描述。由于我无法发送一个实际的$http请求,所以我使用timeout来模拟异步行为。在@Gloopy的帮助下,从我的模型到视图的数据绑定工作正常

现在,当我使用$http而不是$timeout(在本地测试)时,我可以看到异步请求是成功的,数据在我的服务中被json响应填充。但是,我的观点并没有更新。

在这里更新Plunkr


当前回答

Tosh shimayama有一个解决方案,但你可以简化很多,如果你使用$http返回承诺,承诺可以返回一个值:

app.factory('myService', function($http, $q) {
  myService.async = function() {
    return $http.get('test.json')
    .then(function (response) {
      var data = reponse.data;
      console.log(data);
      return data;
    });
  };

  return myService;
});

app.controller('MainCtrl', function( myService,$scope) {
  $scope.asyncData = myService.async();
  $scope.$watch('asyncData', function(asyncData) {
    if(angular.isDefined(asyncData)) {
      // Do something with the returned data, angular handle promises fine, you don't have to reassign the value to the scope if you just want to use it with angular directives
    }
  });

});

coffeescript中的一个小演示:http://plunker.no.de/edit/ksnErx?live=preview

你的活塞更新了我的方法:http://plnkr.co/edit/mwSZGK?p=preview

其他回答

我认为更好的方式是这样的:

服务:

app.service('FruitsManager',function($q){

    function getAllFruits(){
        var deferred = $q.defer();

        ...

        // somewhere here use: deferred.resolve(awesomeFruits);

        ...

        return deferred.promise;
    }

    return{
        getAllFruits:getAllFruits
    }

});

在控制器中,你可以简单地使用:

$scope.fruits = FruitsManager.getAllFruits();

Angular会自动把解析后的awesomfruits放到$scope.fruits中。

因为它是异步的,$作用域在ajax调用完成之前获取数据。

你可以在你的服务中使用$q来创造承诺,并把它还给 控制器和控制器获得的结果在then()调用违背承诺。

为您服务,

app.factory('myService', function($http, $q) {
  var deffered = $q.defer();
  var data = [];  
  var myService = {};

  myService.async = function() {
    $http.get('test.json')
    .success(function (d) {
      data = d;
      console.log(d);
      deffered.resolve();
    });
    return deffered.promise;
  };
  myService.data = function() { return data; };

  return myService;
});

然后,在控制器中:

app.controller('MainCtrl', function( myService,$scope) {
  myService.async().then(function() {
    $scope.data = myService.data();
  });
});

我也有同样的问题,但当我在互联网上冲浪时,我明白$http返回默认的承诺,然后我可以在返回“数据”后使用“然后”。看看代码:

 app.service('myService', function($http) {
       this.getData = function(){
         var myResponseData = $http.get('test.json').then(function (response) {
            console.log(response);.
            return response.data;
          });
         return myResponseData;

       }
});    
 app.controller('MainCtrl', function( myService, $scope) {
      // Call the getData and set the response "data" in your scope.  
      myService.getData.then(function(myReponseData) {
        $scope.data = myReponseData;
      });
 });

在将UI绑定到数组时,您需要确保通过将长度设置为0并将数据推入数组来直接更新相同的数组。

而不是这个(设置一个不同的数组引用数据,你的UI不会知道):

 myService.async = function() {
    $http.get('test.json')
    .success(function (d) {
      data = d;
    });
  };

试试这个:

 myService.async = function() {
    $http.get('test.json')
    .success(function (d) {
      data.length = 0;
      for(var i = 0; i < d.length; i++){
        data.push(d[i]);
      }
    });
  };

下面是一个演示,显示了设置一个新数组与清空和添加到现有数组之间的区别。我不能让你的plnkr工作,但希望这对你有用!

Tosh shimayama有一个解决方案,但你可以简化很多,如果你使用$http返回承诺,承诺可以返回一个值:

app.factory('myService', function($http, $q) {
  myService.async = function() {
    return $http.get('test.json')
    .then(function (response) {
      var data = reponse.data;
      console.log(data);
      return data;
    });
  };

  return myService;
});

app.controller('MainCtrl', function( myService,$scope) {
  $scope.asyncData = myService.async();
  $scope.$watch('asyncData', function(asyncData) {
    if(angular.isDefined(asyncData)) {
      // Do something with the returned data, angular handle promises fine, you don't have to reassign the value to the scope if you just want to use it with angular directives
    }
  });

});

coffeescript中的一个小演示:http://plunker.no.de/edit/ksnErx?live=preview

你的活塞更新了我的方法:http://plnkr.co/edit/mwSZGK?p=preview