【问题标题】:What's the difference between this services declaration methods?这个服务声明方法有什么区别?
【发布时间】:2013-02-20 11:06:39
【问题描述】:

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

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

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

【问题讨论】:

    标签: javascript angularjs frontend angularjs-service


    【解决方案1】:

    这里有一些东西要分开。

    对象与承诺

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

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

    承诺与回调

    Promise 很棒 - 我们应该利用它们。传入回调很好,但它也非常有限。通过 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 方法的对象,其中每个方法都返回一个承诺。如果您的服务只是获取一些数据一次,只需返回承诺并完成它。

    【讨论】:

    • 如果我想做 CRUD 服务,那么第一种方法会更好?
    • @YahyaKACEM 绝对!因为我不经常使用ngResource,所以我就是这样做“伪装”的。
    • 谢谢,我会那样做的。
    【解决方案2】:

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

    请注意,这应该围绕测试等进行计划 - 从个人使用 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;
       }]);
    

    【讨论】:

    • 虽然第一种方法也不会阻止你声明私有成员(在return语句之前)。
    • 正确,我认为我的例子不够具体。如果您只是在声明之前返回,您将无法引用该对象的属性 - 即 public.myproperty
    【解决方案3】:

    第一个示例使 HTTP 请求的异步对服务用户显式,我认为,这比向服务用户提供一个 promise 对象(这是第二个示例中的“数据”)并让用户继续其命令式操作,可能取决于尚未填写的“数据”对象。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 2015-06-07
        • 2012-04-01
        • 2016-05-08
        • 2016-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多