从angularjs调用Rest API的最佳方法是什么?

时间:2013-08-30 09:41:56

标签: angularjs

从角度js调用REST API请求的位置?

即。来自控制器,模块,服务,工厂。我完全感到困惑,它应该是正确的方法吗?

6 个答案:

答案 0 :(得分:11)

您可以使用resources或构建实现http调用的服务。

如果您想使用资源,请记住:

  1. 包含您可以找到here
  2. 的angular-resource.js文件
  3. 包含在您的模块声明中以包含ngResource模块依赖项,如下所示:angular.module('myApp',['ngResource'])
  4. 之后,您可以这种方式声明资源:

    function MyController($scope, $resource){
      var User = $resource('/user/:userId', {userId:'@id'});
      var user = User.get({userId:123}, function() {
        user.abc = true;
        user.$save();
      });
    }
    

    或者,如果您需要更深层次的粒度,请使用服务,例如

    angular.module('myApp')
    .factory('MyAPIService', function($http){
      var apiurl, myData;
      return {
        getData: function(){
          $http.get(apiurl)
          .success(function(data, status, config, headers){
            myData = data;
          })
          .error(function(){ //handler errors here
          });
        },
        data: function() { return myData; }
      };
    });
    

    我发现服务很棒,因为它能够在控制器之间共享数据,所以你可以将它们注入控制器,如此

    myapp.controller('MyController', function($scope, MyAPIService){
      $scope.data = MyAPIService.data();
      // etc.
    
    });
    

答案 1 :(得分:11)

以下是我认为最佳做法:

  • 使用工厂服务来处理访问RESTful web api的机制
  • 将工厂服务注入需要访问的控制器
  • 在工厂中使用承诺解决拒绝来自$ http电话的响应
  • promise允许控制器确定它应如何响应RESTful调用的结果。例如,它可能想要调用Toast弹出窗口来通知用户任何问题。

这保持了数据服务层,业务逻辑和前端UI之间的良好分离。它还将任何一层更改的后果限制为其他层。

答案 2 :(得分:3)

我们这样做,将http服务写为factory方法。

根据评论进行编辑以使用Promise API

 var MyApp = angular.module('App', []);

 MyApp .factory('ApiFactory', ['$http',
        function ($http) {
            return {
               getUsers: function (rowcount) {
                var promise = $http.get('api/Users/' + rowcount) .then(function(response) {
                return response.data;
              }, function (error) {
                //error
            })
            return promise;
           }
         }
       }
   ]);

现在您可以在controller中使用它。

MyApp .controller('MyController', ['$scope', 'ApiFactory',
  function ($scope, ApiFactory) {

    $scope.Users = null;

    ApiFactory.getUsers(count).then(function(data)
    {
      $scope.Users = data;
    });
 } 
 ]);

答案 3 :(得分:2)

您可以使用restangular https://github.com/mgonto/restangular

你会像那样打电话给你的api:

// Only stating main route
Restangular.all('accounts')

// Stating main object
Restangular.one('accounts', 1234)

答案 4 :(得分:1)

只要您使用$ http服务,它就没有任何区别

虽然有提供程序方法声明您应该在客户端和服务器端都有数据提供程序

对于这个问题,我建议一个工厂公开你想要的方法,并使用$ http服务本身

答案 5 :(得分:1)

如果要在多个控制器中使用该REST API调用,最好创建一个作为依赖项注入到需要它的控制器中的服务。如前所述,您希望使用$ resource来处理RESTful API。

的index.html:

<!-- Include Angular and angular-resources -->
<script src="angular.js"></script>
<script src="angular-resource.js"></script>

<!-- Set up your angular module -->
<div ng-app="RESTfulServiceExample">
    <div ng-controller="HomeController">
        <ul>
            <li ng-repeat="game in games">{{game.GameName}}</li>
        </ul>
    </div>
</div>

<script>
    // Inject angular-resource as ngResource into your module
    var gameListApp = angular.module('RESTfulServiceExample', ['ngResource']);

    // Create a service to call API which can be used by many controllers
    gameListApp.factory('GameService', ['$resource', function($resource) {
        return $resource('/game/:gameId', {gameId: '@id'});
    }]);

    // Create a controller that uses your service
    gameListApp.controller('HomeController', function($scope, GameService) {
        // GET: /game/
        var games = GameService.query();

        // Use response in HTML template
        $scope.games = games;
    });

    // Another controller could use the same service
    gameListApp.controller('GameController', function($scope, GameService) {
        // use GameService for another purpose
    });
</script>

参考:AngularJS: $resource