AngularJS服务继承

Ale*_*xey 16 javascript angularjs

我有下一个服务:

angular.module('app').service('BaseService', function (alertService) {
   var service = {};
   service.message =  "Hello";
   service.perform = function () {
        alertService.add("success",service.message);
   };
   return service;
});
Run Code Online (Sandbox Code Playgroud)

现在我想在一些'ChildService'中继承这个服务,并在"World!"上覆盖重写消息.我希望调用ChildService.perform()会显示"World!"的警告.

这样做的正确方法是什么?

Vad*_*dim 31

AngularJS没有提供直接实现服务继承的任何机制,但是对于您的情况,您可以使用$ provide.decorator来扩展BaseService自身,或者像ChildService使用普通JavaScript 的另一个原型一样使用它.在我的实践中,为了获得具有可配置状态和行为的服务,我使用提供者.在以下所有示例中,控制台输出将为World.

装饰

如果您不需要BaseService模块中的原件,可以装饰它

Plunker

function AlertService() {
  this.add = function(level, message) {
    switch(level) {
      case 'success':
        console.log(message);
    }
  }
}

function BaseService(alertService) {
  this.message =  "Hello";
  this.perform = function () {
    alertService.add("success",this.message);
  };
}

angular.
  module('app',[]).
  config(['$provide', function($provide) {
    $provide.decorator('BaseService', function($delegate) {
      $delegate.message = 'World';
      return $delegate;
    });
  }]).
  service('alertService', AlertService).
  service('BaseService', ['alertService',BaseService]).
  controller('ctrl', ['BaseService', function(baseService) {
    baseService.perform();
  }]);
Run Code Online (Sandbox Code Playgroud)

原型继承

Plunker

function AlertService() {
  this.add = function(level, message) {
    switch(level) {
      case 'success':
        console.log(message);
    }
  }
}

function BaseService(alertService) {
  this.message =  "Hello";
  this.perform = function () {
    alertService.add("success",this.message);
  };
}

function ChildService(BaseService) {
  angular.extend(ChildService.prototype, BaseService);
  this.message = "World";
}

angular.
  module('app',[]).
  service('alertService', AlertService).
  service('BaseService', ['alertService',BaseService]).
  service('ChildService', ['BaseService',ChildService]).
  controller('ctrl', ['ChildService', function(ChildService) {
    ChildService.perform();
  }]); 
Run Code Online (Sandbox Code Playgroud)

提供商

Plunker

function AlertService() {
  this.add = function(level, message) {
    switch(level) {
      case 'success':
        console.log(message);
    }
  }
}

function BaseService() {
  var message =  "Hello";

  this.setMessage = function(msg) {
    message = msg;
  }

  function Service(alertService) {
    this.perform = function () {
      alertService.add("success", message);
    };
  }

  function Factory(alertService) {
    return new Service(alertService);
  }

  this.$get = ['AlertService', Factory];
}

angular.
  module('app',[]).
  provider('BaseService', BaseService).
  config(['BaseServiceProvider', function(baseServiceProvider) {
    baseServiceProvider.setMessage('World');
  }]).
  service('AlertService', AlertService).
  controller('ctrl', ['BaseService', function(baseService) {
    baseService.perform();
  }]);
Run Code Online (Sandbox Code Playgroud)

  • 装饰器不是一种继承形式 - 它严格来说是给定服务的装饰,例如在继承中你有两个最终的工件:BaseService < - 继承ChildService,而装饰后你只有BaseService. (3认同)
  • @Sacho我知道装饰器不是继承形式,但是我声称为了获得与其他服务有点不同的服务(并且其他服务没有以其原始形式使用),不需要继承并且可以使用现有服务的装饰器. (2认同)

rah*_*ser 14

我会修改你的代码:

app.factory('BaseService', function () {
   //var service = {}; 
   function service(){
       this.message = "hello";
   }; 
   service.prototype.perform = function () {
        console.log('perfom', this.message);
   };
   return new service();
});
Run Code Online (Sandbox Code Playgroud)

(我只是为console.log()更改alertService; ..)

然后像这样实现继承:

app.factory('childBaseService',['BaseService', function(BaseService){
    var childBaseService = function(){
            BaseService.constructor.call(this)
            this.message = 'world!';
    };

    childBaseService.prototype = Object.create(BaseService.constructor.prototype);
    childBaseService.prototype.constructor = childBaseService;

    return new childBaseService();

}]);
Run Code Online (Sandbox Code Playgroud)

您可以看到一个如何工作的示例 ..最后,BaseService和childService将是BaseService构造函数(服务)的实例.

console.log(BaseService instanceof BaseService.constructor); //true
console.log(childBaseService instanceof BaseService.constructor); //true
Run Code Online (Sandbox Code Playgroud)


Sac*_*cho 5

这是一个基于构造函数/新继承(我通常建议反对)的示例.

BaseService.$inject = ['alertService']
function BaseService(alertService) {
    this.message = 'hello'
    this.alertService = alertService
}

BaseService.prototype.perform = function perform() {
    this.alertService.add("success",this.message);
}


ChildService.$inject = ['alertService']
function ChildService(alertService) {
    this.message = 'hello world'
    this.alertService = alertService
}

ChildService.prototype = Object.create(BaseService.prototype)
Run Code Online (Sandbox Code Playgroud)

然后你只需将这些作为服务包括在内:

angular.module('app')
    .service('BaseService', BaseService)
    .service('ChildService', ChildService)
Run Code Online (Sandbox Code Playgroud)