3

声明服务的最佳方式是什么我发现这两种不同的方式我似乎看不出区别:第一种方法:

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

4 回答 4

5

这里有几件事要分开。

对象与承诺

服务是单例的,因此在第二种方法中(仅返回承诺)您的数据将永远不会再次更新。这通常是想要的结果。在您的第一种方法中,它每次都会被称为新鲜(尽管$http有一个cache选项)。

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

承诺与回调

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

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...
  };
}]);

然后只考虑上面讨论的 Object vs Promise。

结论

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

于 2013-03-05T21:18:37.790 回答
0

后者需要预知 url回调函数。后者允许您同时设置目标 url回调,这更加灵活。在大多数情况下,我建议使用前者,但这实际上取决于您要做什么。

于 2013-03-05T21:09:43.443 回答
0

第一个示例为服务用户明确了 HTTP 请求的异步性,我认为这比给服务用户一个 promise 对象(这是第二个示例中的“数据”)并让用户继续进行更可取它的命令式操作,可能取决于尚未填充的“数据”对象。

于 2013-03-05T21:10:30.680 回答
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;
   }]);
于 2013-03-05T21:12:42.083 回答