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