繁体   English   中英

在AngularJS中为$ http联系REST API设置服务或工厂的最佳实践

[英]Best practice to set up a service or factory for $http contacting to REST API in AngularJS

我在AnguarJS服务中创建了$ http和REST API接口作为一个函数,它被注入不同的控制器,如下所示:

// Global service to share between states
.service("appSharedService", ['$http', function($http) {
  // Method: Returns list of all cities.
  this.restCitiesGet = function() {
     return $http.get('http://example/nkhorasaniec7/api/v0/city');
  };

  // Method:
  this.citiesGet = function() {
    this.restCitiesGet().success(function (data) {
        console.log(data);
        return data;
      })
  };
}])

的console.log(数据); 当我调用citiesGet()时返回正确的json输出。

// Main controller that prints list of cities.
.controller('CityList', ['$scope', function($scope, appSharedService) {
  $scope.cities = appSharedService.citiesGet();
  console.log($scope.cities);
}]);

这是我的控制器注入我的服务。 的console.log($ scope.cities); 这里返回undefined。

路由调用此控制器后,$ scope.cities值不会更改。

我的设置有问题吗?

有趣的是,在我改变路由并再次回到这个控制器后,这次$ scope.cities有我的REST数据,一切都很好。

我认为这里的定时或异步功能问题存在问题,我不知道。

编辑:

我可以在我的控制器中使用$ http,这一切都很好:

.controller('CityList', ['$scope', '$http', function($scope, $http, appSharedService) {
  $http.get('http://localhost/nkhorasaniec7/api/v0/city').success(function (data) {
        $scope.cities = data;
      });
}]);

但我想为此实现帮助函数。

我会说通常的方法是将promise直接返回给控制器,就像你上面直接使用http请求一样。

// Global service to share between states
.service("appSharedService", ['$http', function($http) {


// Method: Returning the promise
this.citiesGet = function() {
  return $http.get('http://example/nkhorasaniec7/api/v0/city');

 };
}])

控制器:

  .controller('CityList', ['$scope', '$http', function($scope, $http, appSharedService) {
appSharedService.citiesGet().success(function (data) {
      $scope.cities = data;
    });
 }]);

我认为你对时间问题是正确的。 根据我的理解,你得到了一个承诺,目前你做的是console.log($scope.cities)尚未解决。

如果在页面中使用$scope.cities ,则应在加载后立即看到结果。 如果你真的想记录,另一种选择是使用promise then函数。

$scope.cities = appSharedService.citiesGet().then(function(data) {
  console.log(data);
  return data;
};

回答我自己的问题:

我试图在我的视图中使用ng-controller定义的控制器中发生这种情况而不是链接到路由器的控制器 (否则你可以使用像这样延迟AngularJS路由更改的解析属性, 直到模型加载以防止闪烁 )。

我想使用REST作为工厂/服务帮助函数使用REST作为更干净的代码。

// Global service to share between states
.service("appSharedService", ['$http', '$q', function($http, $q) {
  this.citiesGet = function() {
      var deferred = $q.defer();
      $http({method: 'GET', url: 'http://localhost/nkhorasaniec7/api/v0/city'}).success(function(data) {
        deferred.resolve(data);
      }).error(function(data, status) {
        deferred.reject(data);
      });
      return deferred.promise;
  };
}])

我在这里使用了角度$ q的承诺。

// Our main controller that prints list of cities.
.controller('CityList', ['$scope', 'appSharedService', function($scope, appSharedService) {
  var promise = appSharedService.citiesGet();
  promise.then(
        function(data){$scope.cities = data;}
        ,function(reason){alert('Failed: ' + reason);}
  );
}])

然后使用那个函数来使用那个承诺。 现在它总是在模板加载的任何情况下更新$ scope.cities(不仅仅是在ng-view中)

您可以使用$ q服务

.service("appSharedService", ['$http', '$q', function($http, $q) {
  // Method: Returns list of all cities.
  this.restCitiesGet = function() {

    var deffered = $q.defer();
     $http.get('http://example/nkhorasaniec7/api/v0/city').then(
      //success
      function(response){
         deffered.resolve(response.data);},
      //error
         deffered.reject();

      );
    return deffered 
  };

然后你可以在你的控制器中使用promise

    .controller('CityList', ['$scope', function($scope, appSharedService) {
        $scope.cities = []
       appSharedService.citiesGet().then(
        //success
        function(result){
        angular.copy(result, $scope.cities)
        console.log($scope.cities);
       }, 
      //error
      function(){
      console.log("load error");

});

    }]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM