1

我有从 api 获取数据的自定义模块。它是异步的,所以我使用 defer 。

angular.module('module', []).factory('api', function($q){
    var $scope;
    return {
        setScope: function(scope){ $scope = scope; },
        getPic:function(){
            var def = $q.defer();
            $.ajax({
                url: 'https://graph.facebook.com/shaverm/picture?redirect=false',
                dataType: 'jsonp',
                success: function(r){
                    def.resolve(r.data.url);
                    $scope.$apply();
                },
            });
            return def.promise
        }
    }
});

它工作正常,但我担心在模块中使用 scope.$apply 。

这是示例http://jsfiddle.net/mfbFs/

可以改进吗?

4

2 回答 2

2

你为什么要使用 jQuery 的 ajax,而 Angular 自带了它并且有一个内置的 Promise?

angular.module('module', []).factory('api', function($http){
  return {
    getPic: function(){
      return $http.jsonp('https://graph.facebook.com/shaverm/picture?redirect=false&callback=JSONP_CALLBACK');
    }
  };
});

简单多了!并且无需担心摘要 - 您的控制器已经确保在它应该发生的时候发生。

于 2013-01-27T22:51:02.090 回答
1

您无需$scope在调用 API 之前设置,只需在服务上注入$rootScope并在该范围内调用$apply()(或$digest()),如下所示:

angular.module('module', []).factory('api', function($q, $rootScope){
    return {           
        getPic:function(){
            var def = $q.defer();
            $.ajax({
                url: 'https://graph.facebook.com/shaverm/picture?redirect=false',
                dataType: 'jsonp',
                success: function(r){
                    def.resolve(r.data.url);
                    $rootScope.$apply();
                },
            });
            return def.promise
        }
    }
});
function demoCtrl ($scope, api){         
     $scope.url = api.getPic();   
}
于 2013-01-27T22:48:21.120 回答