15

应该从哪里从 Angular js 调用 REST API 请求?

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

4

6 回答 6

12

以下是我认为的最佳实践:

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

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

于 2014-09-01T20:20:20.877 回答
11

您可以使用资源,也可以构建实现 http 调用的服务。

如果要使用资源,请记住:

  1. 包含您可以在此处找到的 angular-resource.js 文件
  2. 在您的模块声明中包含 ngResource 模块依赖项,如下所示:angular.module('myApp',['ngResource'])

之后,您可以以这种方式声明资源:

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.

});
于 2013-08-30T09:47:38.153 回答
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;
    });
 } 
 ]);
于 2013-08-30T09:54:45.140 回答
2

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

你会这样调用你的api:

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

// Stating main object
Restangular.one('accounts', 1234)
于 2013-08-30T10:08:25.453 回答
1

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

尽管有提供者方法表明您应该在客户端和服务器端都有一个数据提供者

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

于 2013-08-30T09:51:57.607 回答
1

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

索引.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

于 2014-03-01T11:31:50.520 回答