2014-10-17 72 views
1

我想在控制器完成剩下的任务之前等待服务$ http结果。 我为myData测试了一些硬编码的JSON,它在控制器中是可见的,但只要我试图用$ http请求填充myData,控制器就不会等待它,只是通过代码的其余部分。 Chrome webdevelopper的网络标签显示了该请求的预期结果。

我已经具备以下条件:

var ListerApp = angular.module('ListerApp',[ 
    'ListerAppFilters', 
    'sharedFactoryApp', 
    'sharedServiceApp', 
    'ListerAppController', 
    'infinite-scroll', 
    'angular-inview', 
    'ngRoute' 
]); 

ListerApp.config(['$routeProvider', '$httpProvider', function($routeProvider, $locationProvider) { 
    $routeProvider 
     .when('/list', 
      { 
       templateUrl: '/assets/services/partials/list.html', 
       controller: 'ListerCtrl', 
       resolve : { 
        'sharedServiceAppData': function($sharedServices){ 
         // sharedFactoryAppData will also be injectable in your controller, if you don't want this you could create a new promise with the $q service 
         return $sharedServices.promise(); 
        } 
       } 
      } 
     ); 
}]); 

angular.module('sharedServiceApp', []).service('$sharedServices', ['$http', '$rootScope', '$q', function($http, $rootScope, $q) { 
    var myData = null; 

    return { 
     promise : function() { 
      if (!myData) { 
       $http({method : 'GET', url : '/shop/api/json', params : { 
         end   : $rootScope.endmarkerSyncDataset, 
         page  : 1, 
         per_page : $rootScope.itemsPerPage 
        } 
       }).success(function (data) { 
        myData = data.data_set; 
        //deferred.resolve(data.data_set); 
       }); 

       // I allready tested this and this is OK: myData = {foo : 'bar'}; 
      } 
     }, 
     getShopData: function() { 
      return myData; 
     } 
    }; 
}]); 

(function(){ 
    var appController = angular.module('ListerAppController', []); 

    appController.controller('ListerCtrl', ['$scope', '$rootScope', '$http', '$filter', '$timeout', '$sharedFactories', '$sharedServices', 
     function($scope, $rootScope, $http, $filter, $timeout, $sharedFactories, $sharedServices) { 
      $scope.items = $sharedServices.getShopData(); 
      console.log($scope.items); // return myData -> null 
     } 
})(); 

回答

3

我已经这样做了一堆倍这里就是我平时做的routeProvider我的决心对象,需要确保你适当地返回所有的承诺以便路由更改等待解析属性。

$routeProvider 
    .when('/path', 
     { 
      templateUrl: 'some/path/to/template.html', 
      controller: 'myCtrl', 
      resolve : { 
       'myData': ['mySrvc',function(mySrvc){ 
        return mySrvc.someMethod().then(function(response){ 
         return response.data; 
        },function(){ 
         return {}; 
        }); 
       }] 
      } 
     } 
    ); 

然后,服务:

angular.module('myApp.services').factory('mySrvc',['$http',function($http){ 
    var _url = 'https://someurl.com/path/to/api'; 

    return { 
     someMethod : function(vars){ 
      if(angular.isDefined(vars)){ 
       return $http.post(_url,$.param(vars),{headers:{'Content-Type':'application/x-www.form-urlencoded'}}); 
      }else{ 
       return $http.get(_url); 
      } 
     } 
    }; 
}]); 

然后在控制器你需要对控制器的参数列表的末尾注入的决心参数。

angular.module('myApp.controllers').controller('myCtrl',['$scope','myData',function($scope,myData){ 

}); 

在你的代码,在routeProvider你从没有返回值的函数返回的决心对象,尝试恢复从$http的承诺,然后在成功功能data.data_set值你的服务。

+1

感谢您的帮助。我找到了一些东西,并在下面发布。你的例子帮助我进一步创建一个API类对象。 – poashoas 2014-10-17 15:02:46

0

我找到了类似$ q.defer,resolve和promise的东西。 它阻止了一切,直到达到“承诺”状态。

这里的a link

angular.module('sharedServiceApp', []).service('$sharedServices', ['$http', '$rootScope', '$q', function($http, $rootScope, $q) { 
    var myData = null; 

    return { 
     promise : function() { 
      if (!myData) { 
       var deferred = $q.defer(); 
       $http({method : 'GET', url : '/shop/api/json', params : { 
        end   : $rootScope.endmarkerSyncDataset, 
        page  : 1, 
        per_page : $rootScope.itemsPerPage 
       } 
      }).success(function (data) { 
       myData = data.data_set; 
       deferred.resolve(data.data_set); 
      }).error(function(data, status, headers, config) { 
       deferred.reject("Error: request returned status " + status); 
      }); 
      return deferred.promise; 
     } else { 
      return myData; 
     } 
    }, 
    getShopData: function() { 
     return myData; 
    }, 
    setShopData: function (data) { 
     myData= data; 
    } 
}; 

}]);

+1

因为'$ http'已经返回一个承诺,所以在这个实例中你确实不需要使用'$ q'。只需从'$ http'调用返回承诺,然后在* success *和* error *函数中确保返回数据或错误状态。 – 2014-10-17 15:34:42

+0

就是这样!谢谢一堆。这真的帮了我很多。 – poashoas 2014-10-17 17:04:53

+0

当然没问题,很乐意帮忙。 – 2014-10-20 13:09:42