Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/456.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS服务继承_Javascript_Angularjs - Fatal编程技术网

Javascript AngularJS服务继承

Javascript AngularJS服务继承,javascript,angularjs,Javascript,Angularjs,我有下一项服务: angular.module('app').service('BaseService', function (alertService) { var service = {}; service.message = "Hello"; service.perform = function () { alertService.add("success",service.message); }; return service; });

我有下一项服务:

angular.module('app').service('BaseService', function (alertService) {
   var service = {};
   service.message =  "Hello";
   service.perform = function () {
        alertService.add("success",service.message);
   };
   return service;
});
现在我想在一些“ChildService”中继承这个服务,并在“World!”上覆盖消息。 我希望调用ChildService.perform()将显示带有“World!”的警报


什么是正确的方法呢?

下面是一个基于构造函数/新继承的示例(我通常不建议这样做)

然后,您可以将这些作为服务包括在内:

angular.module('app')
    .service('BaseService', BaseService)
    .service('ChildService', ChildService)

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

装饰师

如果模块中不需要原始的
BaseService
,可以对其进行装饰

原型遗传

提供商


我会稍微修改一下您的代码:

app.factory('BaseService', function () {
   //var service = {}; 
   function service(){
       this.message = "hello";
   }; 
   service.prototype.perform = function () {
        console.log('perfom', this.message);
   };
   return new service();
});
(我只是将您的alertService更改为console.log();…)

然后实现如下继承:

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();

}]);
(function(j){var c=j.module('A',[]);})(angular); // and so on
你可以看到这是如何运作的。。最后,BaseService和childService将是BaseService构造函数(service)的实例


具有ASvc服务的模块A:

(function(angular) {
  var app = angular.module('A', []);

  app.service('ASvc', ['$http', function($http) {
     var ASvc = {
       list: function() {
         return $http({
           method: 'GET',
           url: '/A'
         });
       },

       getInstructions: function(id) {
         return $http({
           method: 'GET',
           url: '/instructions/' + id
         });
       }
     };
     return ASvc;
  }]);
})(angular);
模块B带有从ASvc继承的服务BSvc:

(function(angular) {
  var app = angular.module('B', ['A']);

  app.service('BSvc', ['$http', 'ASvc', function($http, ASvc) {
     var BSvc = {
       list: function() {
         return $http({
           method: 'GET',
           url: '/B'
         });
       }
     };

     BSvc.__proto__ = ASvc; // here you're settting the inheritance
     return BSvc;
  }]);
})(angular);
现在,当您调用
BSvc.getInstructions(30775)时
,调用父服务(
ASvc
getInstructions
函数,调用
BSvc
,调用
BSvc.list()
,调用的方法被
BSvc
中的
ASvc
覆盖。继承权

顺便说一句,当我将
angular
作为参数传递给闭包时,我不直接从闭包中引用全局
angular
变量,而是允许代码缩小器和模糊器执行如下操作:

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();

}]);
(function(j){var c=j.module('A',[]);})(angular); // and so on

记住这是一件好事,我认为这是一个好的实践;p> 使用您喜欢的javascript继承风格,然后将结果对象添加为服务。请记住,由于服务是单例的,所以您可能需要添加一个实例或构造函数。您能否详细说明您的“我通常建议不要”评论?在我看来,这似乎会很好地工作。继承一般来说是很尴尬的——与它的大量使用相比,它只在非常特定的情况下有益。Javascript继承是它上面的一个额外的尴尬层,这是因为
这个
是在函数调用上绑定的。JavaScript中基于构造函数的/经典继承增加了一个额外的混乱层(例如,注意我必须如何使用Objut.Cuto扩展原型对象,考虑要执行超()调用所需的工作,需要用作回调的函数。对象合成更平滑。很好的例子。我认为应该是
this.message
而不是
service.message
,因为您没有使用服务对象。您的示例中没有
Base
类,因此
object.create(Base.prototype)
将抛出错误。我认为应该是
Object.create(BaseService.prototype)
。您的子服务正在丢失它。。在原型化之后,您应该执行childService.prototype.constructor=childService,而且您在继承中缺少一个重要的事实。。调用超类构造函数,child.prototype=object.create(base.prototype)将原型属性和函数传递给新对象。。但是基本it自身的属性和功能不是继承的。装饰器不是继承的一种形式-它严格来说是给定服务的装饰,例如,在继承中,您有两个最终工件:BaseService@Sacho我知道装饰器不是继承的形式,然而,我声称,为了获得与其他服务稍有不同的服务(而另一个服务并没有以其原始形式使用),不需要继承,而可以使用现有服务的装饰器。这是一种“内部”(在服务声明中做事情)的简洁方式,我没有想到:)模糊器参数在这里不算:
1。
您的代码使用了大约15个额外字符<代码>2。
如果不想污染窗口名称空间,可以简单地链接这些调用并保存其他字符:
angular.module('A',[]).service(…).service(…)@BenjaminM好的,也许模糊处理并不完美,但缩小效果很好。在我看来,链式调用会产生非常难看的代码,而且由于我编写的代码大部分时间都会被处理为串联和缩编,因此我非常关心原始代码的易读性。关于闭包,即使它在闭包中引用全局“角度”变量,这也是我自学的习惯,在闭包中封装模块。在最坏的情况下,这根本不会造成伤害。
(function(angular) {
  var app = angular.module('A', []);

  app.service('ASvc', ['$http', function($http) {
     var ASvc = {
       list: function() {
         return $http({
           method: 'GET',
           url: '/A'
         });
       },

       getInstructions: function(id) {
         return $http({
           method: 'GET',
           url: '/instructions/' + id
         });
       }
     };
     return ASvc;
  }]);
})(angular);
(function(angular) {
  var app = angular.module('B', ['A']);

  app.service('BSvc', ['$http', 'ASvc', function($http, ASvc) {
     var BSvc = {
       list: function() {
         return $http({
           method: 'GET',
           url: '/B'
         });
       }
     };

     BSvc.__proto__ = ASvc; // here you're settting the inheritance
     return BSvc;
  }]);
})(angular);
(function(j){var c=j.module('A',[]);})(angular); // and so on