这种服务声明方法有什么区别?

时间:2013-03-05 21:06:52

标签: javascript angularjs frontend angularjs-service

宣布服务的最佳方式是什么我发现这两种不同的方式我似乎无法看出差异: 第一种方法:

angular.module('app', [])
   .factory('Data', ['$http',function($http){
     return {
         get: function(fileName,callback){
              $http.get(fileName).
              success(function(data, status) {
                  callback(data);
              });
         }
     };
   }]);

第二种方法:

angular.module('app', [])
   .factory('Data', ['$http', function($http){
     var Url   = "data.json";
     var Data = $http.get(Url).then(function(response){
       return response.data;
     });
     return Data;
   }]);

哪一个更好,为什么? 提前致谢。

4 个答案:

答案 0 :(得分:5)

这里有一些事情要分开。

对象与承诺

服务是单身,所以在第二种方法(仅返回承诺)中,您的数据将永远不会再次更新。这通常是理想的结果。在第一种方法中,每次都会调用它(尽管$httpcache选项)。

从我的角度来看,如果有多种方法(例如getcreatedelete等),则只返回服务对象,或者需要多次调用。否则,我们只是在堆积如山。

承诺与回调

承诺 awesome - 我们应该利用它们。传递回调很好,但它也非常有限。有了承诺,我们可以轻松地将它们链接在一起,例如:

Data.get()
.then( massageDataFn )
.then( secondMassageFn )
.then(function ( data ) {
  $scope.items = data;
});

此外,$http已经返回一个承诺。为什么扔掉它?

方法参数

你的前者(对象方法)接受了一些参数。虽然我对传入URL的控制器持谨慎态度,但还有一些的情况需要它。但你可以通过 返回一个函数而不是一个对象来做到这一点:

.factory( 'Data', [ '$http', function ( $http ) {
  return function ( fileName, callback ) {
    // $http call here...
  };
}]);

然后只考虑对象与承诺,如上所述。

<强>结论

如果您的服务具有API,则返回具有公共API方法的对象,其中每个方法都返回一个promise。如果您的服务只是以获取一些数据,那么只需返回承诺并完成它。

答案 1 :(得分:0)

后者需要预知url 回调函数。后者允许您设置目标URL 回调,这更灵活。在大多数情况下,我建议与前者合作,但这实际上取决于你要做的事情。

答案 2 :(得分:0)

第一个示例使HTTP请求的异步显式为服务用户,我认为,最好将服务用户交给一个promise对象(这是第二个样本中的“Data”)并让它用户继续执行其命令操作,可能取决于尚未填充的“数据”对象。

答案 3 :(得分:0)

您的第二种方法稍微冗长一点,但一个主要好处是能够创建私有属性/方法,并且只返回公共对象。

请注意,这应该围绕测试等进行规划 - 从Angular的个人经验来看,私有方法和属性更难以进行单元测试等。

举个例子:

angular.module('app', [])
   .factory('Data', ['$http', function($http){
        var private = {
            property: 100,
            method: function(data) {
                return data * 2;
            }
        };
        var public = {
            property: true,
            property_two: false,
            method: function(data) {
                return private.method(data + private.property);
            }
        };
        return public;
   }]);