Angular $ http vs service vs ngResource

ada*_*amK 41 angularjs

我想了解使用简单的$ http请求到服务器和/或在服务中包装该请求与使用ngResource对象(除了显而易见的RESTful资源之外)的优点/缺点.

根据我的理解,$ http请求是低级别但非常灵活且可配置,而在处理RESTful API时,ngResource对象使通信变得非常简单.

我想我所询问的是一个非常简单的场景,比如从服务器检索数据(对象数组的GET请求说)是简单地使用$ http请求而不是将它包装在服务中更有效(应该总是这样吗?)或使用ngResource对象?

任何想法在这里将不胜感激.例如,可以缓存$ http响应,可以使用ngResource吗?谢谢.

sha*_*ain 42

我决定将这个问题制定成一个答案,因为在评论中我们基本上得出了你想知道的内容:

使用$ http或$ resource仍然可以缓存结果,你指出了在你的问题中使用一个而不是另一个的原因.如果你有一个RESTful接口,那么使用$ resource会更好,因为你最终会编写一个RESTful接口常见的样板代码,如果你没有使用RESTful服务那么$ http更有意义.您可以通过http://www.pseudobry.com/power-up-http-with-caching/缓存数据

我认为将$ http或$ resource请求放入服务通常会更好,因为您希望从多个位置访问数据,并且该服务充当单例.所以,基本上你可以处理你想要做的任何类型的缓存,控制器都可以只看到适当的服务来更新自己的数据.我发现控制器中的$ watch组合服务器上的数据并从我的服务方法中返回promises,这使我在如何更新控制器中的内容方面具有最大的灵活性.

我在我的控制器中放了这样的东西,在控制器定义的顶部注入了exampleService.

angular.module("exampleApp", []).service('exampleService', ["$http", "$q" ,function ($http, $q) {
    var service = {
        returnedData: [],
        dataLoaded:{},
        getData = function(forceRefresh)
        {
            var deferred = $q.defer();

            if(!service.dataLoaded.genericData || forceRefresh)
            {
                $http.get("php/getSomeData.php").success(function(data){
                    //service.returnedData = data;
                    //As Mark mentions in the comments below the line above could be replaced by
                    angular.copy(data, service.returnedData);
                    //if the intention of the watch is just to update the data
                    //in which case the watch is unnecessary and data can
                    //be passed directly from the service to the controller
                    service.dataLoaded.genericData = true;
                    deferred.resolve(service.returnedData);
                });
            }
            else
            {
                deferred.resolve(service.returnedData);
            }

            return deferred.promise;
        },
        addSomeData:function(someDataToAdd)
        {
            $http.post("php/addSomeData.php", someDataToAdd).success(function(data){
                service.getData(true);
            });
        }
    };
    service.getData();
    return service;
}]).controller("ExampleCtrl", ["$scope", "exampleService", function($scope, exampleService){
  //$scope.$watch(function() {return exampleService.returnedData}, function(returnedData){
  //  $scope.myModel.someData = returnedData;
  //});
  //if not using angular.copy() in service just use watch above
  $scope.myModel.someData = exampleService.returnedData;
}]);
Run Code Online (Sandbox Code Playgroud)

另外,这是一个来自Angular团队最佳实践的精彩视频,我仍然会重新观看并逐渐吸收.

http://www.youtube.com/watch?v=ZhfUv0spHCY

特别是在服务与控制器上:http://www.youtube.com/watch?v = ZhfUv0spHCY&t = 26m41s

  • +1.如果在服务中使用`angular.copy(data,service.returnedData)`,则可以消除控制器中的`$ watch`.这样,您将更新相同的数组,而不是分配新的数组.对于工作的plunker,请参阅http://stackoverflow.com/questions/17416599/should-services-expose-their-asynchronicity (13认同)

Rod*_*ati 5

与是否可以缓存相比,有一个更有意义的区别.

使用资源将消除在服务或返回的数据上设置$ watch的需要.你根本不必处理承诺.从本质上讲,它消除了在他的例子中做shaunhusain正在做的任何事情的需要.

对resource方法的调用返回与该资源关联的结构的空实例,您可以并且应该直接绑定它.同一个实例将在稍后的某个时间填充数据.由于您已绑定到实例,因此当它填写时,您的显示将自动更新.

资源还可以提供封装的方法来转换它提供的服务的请求和响应,使其对资源的客户端都是不可见的.

资源就像类固醇服务.