[英]Angular service inheritance using Object.create()
I'm trying to use inheritance in angular services, as explained here: http://blog.mgechev.com/2013/12/18/inheritance-services-controllers-in-angularjs/ , I want to use the "Inject the parent" method. 我正在尝试在角度服务中使用继承,如此处所述: http : //blog.mgechev.com/2013/12/18/inheritance-services-controllers-in-angularjs/ ,我想使用“注入父”方法。
However, it doesn't seem to work, and I can't see why. 但是,它似乎不起作用,我也看不出原因。
var myApp = angular.module('myApp',[]);
angular.module('myApp').controller('MyCtrl', MyCtrl);
angular.module('myApp').factory('BaseModel', BaseModel);
angular.module('myApp').factory('ThreadModel', ThreadModel);
angular.module('myApp').factory('PostModel', PostModel);
function MyCtrl($scope, ThreadModel, PostModel) {
$scope.tableNameForThreads = ThreadModel.getTableName();
$scope.tableNameForPosts = PostModel.getTableName();
}
function BaseModel() {
var tableName = "";
var service = {
init: init,
getTableName: getTableName
};
return service;
function getTableName() {
return tableName;
}
function init(theTableName) {
tableName = theTableName;
}
}
function ThreadModel(BaseModel) {
var service = Object.create(BaseModel);
service.init("threads");
return service;
}
function PostModel(BaseModel) {
var service = Object.create(BaseModel);
service.init("posts");
return service;
}
The result is that ThreadModel.getTableName() returns "posts" in stead of "threads". 结果是ThreadModel.getTableName()返回“ posts”而不是“ threads”。
I tried both Object.create(...)
and angular.copy(BaseModel, this)
, but both don't seem to make a deep copy. 我尝试了
Object.create(...)
和angular.copy(BaseModel, this)
,但似乎都没有进行深拷贝。
JSFIDDLE: http://jsfiddle.net/dirkpostma/Lvc0u55v/3989/ JSFIDDLE: http : //jsfiddle.net/dirkpostma/Lvc0u55v/3989/
What am I doing wrong here? 我在这里做错了什么?
The problem is that with this set up using Object.create
you produce services with the tableName
variable stored in the same common closure (BaseModel function). 问题在于,使用
Object.create
进行此设置时,您将使用tableName
变量存储在相同的通用闭包(BaseModel函数)中来产生服务。 To put it simply, init
method modifies the same local tableName
variable. 简单地说,
init
方法修改了相同的本地tableName
变量。
You could fix it like this: 您可以这样解决:
function BaseModel() {
var service = {
init: init,
getTableName: getTableName
};
return service;
function getTableName() {
return this._tableName;
}
function init(theTableName) {
this._tableName = theTableName;
}
}
Note, that getTableName
and init
methods now work with instance property this._tableName
which is not shared between TableModel
and PostModel
instances. 请注意,
getTableName
和init
方法现在与实例属性this._tableName
,该属性在TableModel
和PostModel
实例之间不共享。
Demo: http://jsfiddle.net/Lvc0u55v/3991/ 演示: http : //jsfiddle.net/Lvc0u55v/3991/
@dfsq has already well explained and given a simple solution. @dfsq已经很好地解释了,并给出了一个简单的解决方案。 I put here what I am thinking about this issue.
我把关于这个问题的想法放在这里。
In your code Object.create(BaseModel)
creates a new object whose prototype is a returned value of BaseModel
function. 在您的代码中,
Object.create(BaseModel)
创建一个新对象,其原型是BaseModel
函数的返回值。 In those children models init
method modifies tableName
within the local scope of BaseModel
function. 在那些子模型中,
init
方法会在BaseModel
函数的本地范围内修改tableName
。 If you replace tableName
with this.tableName
, that will work as you expected: both init
and getTableName
methods will actually modify/call tableName
property of service
variable within ThreadModel
or PostModel
functions. 如果用
this.tableName
替换tableName
,它将按预期工作: init
和getTableName
方法实际上将在ThreadModel
或PostModel
函数中修改/调用service
变量的tableName
属性。 But it looks complicated. 但是看起来很复杂。
In your case I would like suggest the following service inheritance solution, which would be clearer. 对于您的情况,我想提出以下服务继承解决方案,这将更加清楚。 There is an other post that can be interesting.
还有另一篇可能很有趣的文章。
var myApp = angular.module('myApp', []);
angular.module('myApp').controller('MyCtrl', MyCtrl);
angular.module('myApp').service('BaseModel', BaseModel);
angular.module('myApp').service('ThreadModel', ['BaseModel', ThreadModel]);
angular.module('myApp').service('PostModel', ['BaseModel', PostModel]);
function MyCtrl($scope, ThreadModel, PostModel) {
$scope.tableNameForThreads = ThreadModel.getTableName();
$scope.tableNameForPosts = PostModel.getTableName();
}
function BaseModel() {
this.tableName = "";
this.getTableName = function() {
return this.tableName;
}
this.init = function(theTableName) {
this.tableName = theTableName;
}
}
function ThreadModel(BaseModel) {
angular.extend(ThreadModel.prototype, BaseModel);
this.tableName = "threads";
}
function PostModel(BaseModel) {
angular.extend(PostModel.prototype, BaseModel);
this.tableName = "posts";
}
JSFiddle: http://jsfiddle.net/Lvc0u55v/3993/ JSFiddle: http : //jsfiddle.net/Lvc0u55v/3993/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.