【问题标题】:how can i extend a service我如何扩展服务
【发布时间】:2013-03-08 12:24:19
【问题描述】:

我对@9​​87654321@ 还很陌生,找不到任何文档或示例。我要做的是扩展基本服务,以便我可以使用其他服务的基本服务下定义的方法。因此,例如说我有如下基本服务。

angular.module('myServices', []).

    factory('BasicService', function($http){
        var some_arg = 'abcd'
        var BasicService = {
            method_one: function(arg=some_arg){ /*code for method one*/},
            method_two: function(arg=some_arg){ /*code for method two*/},
            method_three: function(arg=some_arg){ /*code for method three*/},
        });
        return BasicService;
    }   
);

现在我想定义一个从上述BasicService 扩展的扩展服务,以便我可以从我的扩展服务中使用 BasicService 下定义的方法。可能是这样的:

    factory('ExtendedService', function($http){
        var ExtendedService = BasicService();
        ExtendedService['method_four'] = function(){/* code for method four */}
        return ExtendedService;
    }

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    更简洁和命令式的方式

    .factory('ExtendedService', function($http, BasicService){
    
        var extended = angular.extend(BasicService, {})
        extended.method = function() {
            // ...
        }
        return extended;
    }
    

    【讨论】:

    • 我认为扩展空对象而不是原始服务更好:var extended = angular.extend({}, BasicService)copy 也将创建新实例而不是扩展它的浅拷贝
    【解决方案2】:

    您的ExtendedService应该注入BasicService以便能够访问它。除此之外,BasicService 是一个对象字面量,因此您实际上不能将其称为函数 (BasicService())。

    .factory('ExtendedService', function($http, BasicService){
      BasicService['method_four'] = function(){};
      return BasicService;
    }
    

    【讨论】:

    • 如果我们认为 BasicService 是抽象的,我是否说这是最好的方法?因为那样我们将永远不会真正使用 BasicService,而只会使用 ExtendedService,因此可以对其进行文学扩展。
    • 这种方法真的可以吗?鉴于服务是单例的,这意味着 BasicService 上的更改将是永久性的,因此 BasicService 也将被更改。创建 BasicService 的副本并返回该副本的扩展版本不是更好吗?
    【解决方案3】:

    在我看来,更好的方法:

    .factory('ExtendedService', function($http, BasicService){
        var service = angular.copy(BasicService);
    
        service.methodFour = function(){
            //code for method four
        };
    
        return service;
    });
    

    这里至少不会改变继承的服务。

    【讨论】:

    • 我同意,使用 copy() 更有意义,因为您不会更改继承的服务。
    【解决方案4】:

    对不起,如果我在这里发帖,但可能是个不错的地方。 我指的是这个post

    注意扩展服务/工厂,因为它们是单例的 这样您就可以扩展服务/工厂一次。

    'use strict';
                angular.module('animal', [])
                    .factory('Animal',function(){
                            return {
                                vocalization:'',
                                vocalize : function () {
                                    console.log('vocalize: ' + this.vocalization);
                                }
                            }
    
                    });
                    angular.module('dog', ['animal'])
                        .factory('Dog', function (Animal) {
                            Animal.vocalization = 'bark bark!';
                            Animal.color = 'red';
                            return Animal;
                        });
    
                    angular.module('cat', ['animal'])
                       .factory('Cat', function (Animal) {
                            Animal.vocalization = 'meowwww';
                            Animal.color = 'white';
                            return Animal;
                        });
                     angular.module('app', ['dog','cat'])
                    .controller('MainCtrl',function($scope,Cat,Dog){
                         $scope.cat = Cat;
                         $scope.dog = Dog;
                         console.log($scope.cat);
                         console.log($scope.dog);
                        //$scope.cat = Cat;
                    });
    

    如果你喜欢

    'use strict';
                angular.module('animal', [])
                    .factory('Animal',function(){
                        return function(vocalization){
                            return {
                                vocalization:vocalization,
                                vocalize : function () {
                                    console.log('vocalize: ' + this.vocalization);
                                }
                            }
                        }
                    });    
                    angular.module('app', ['animal'])
                        .factory('Dog', function (Animal) {
                            function ngDog(){
                                this.prop = 'my prop 1';
                                this.myMethod = function(){
                                    console.log('test 1');
                                }
                            }
                            return angular.extend(Animal('bark bark!'), new ngDog());
                        })
                        .factory('Cat', function (Animal) {
                            function ngCat(){
                                this.prop = 'my prop 2';
                                this.myMethod = function(){
                                    console.log('test 2');
                                }
                            }
                            return angular.extend(Animal('meooow'), new ngCat());
                        })
                    .controller('MainCtrl',function($scope,Cat,Dog){
                         $scope.cat = Cat;
                         $scope.dog = Dog;
                         console.log($scope.cat);
                         console.log($scope.dog);
                        //$scope.cat = Cat;
                    });
    

    有效

    【讨论】:

    • 很好的说明,但 angular.extend() 通过制作服务副本以更简单的方式处理这一点。
    【解决方案5】:

    我编写了一个 $extend 提供程序,它在后台使用 Backbone 的扩展 -- 因此,您可以在需要时扩展原型和静态属性 -- 另外,您还可以获得父/子构造函数 -- 参见 gist @https://gist.github.com/asafebgi/5fabc708356ea4271f51

    【讨论】:

      【解决方案6】:

      要扩展 Stewie 的答案,您还可以执行以下操作:

      .factory('ExtendedService', function($http, BasicService){
          var service = {
              method_one: BasicService.method_one,
              method_two: BasicService.method_two,
              method_three: BasicService.method_three,
              method_four: method_four
          });
      
          return service ;
      
          function method_four(){
      
          }
      }
      

      这样做的好处是原始服务不会被更改,同时保持其功能。您还可以选择在 ExtendedService 中为 BasicService 中的其他 3 个方法使用您自己的实现。

      【讨论】:

      • 不是海报,但有人可以解释为什么这个解决方案被否决了吗?我觉得很好。
      • 看来,这篇文章被否决了,因为您需要列出从父对象获得的方法和字段。由于某些原因,这是不好的做法。从技术上讲,这也不是纯粹的继承。
      猜你喜欢
      • 2019-04-21
      • 2011-10-19
      • 2017-12-27
      • 1970-01-01
      • 2012-10-12
      • 2011-05-30
      • 2018-06-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多