使用Object.create()进行角度服务继承

时间:2016-05-14 08:50:49

标签: javascript angularjs oop inheritance factory

我尝试在角度服务中使用继承,如下所述: http://blog.mgechev.com/2013/12/18/inheritance-services-controllers-in-angularjs/,我想使用"注入父母"方法

然而,它似乎不起作用,我不明白为什么。

$delimiter = 'EOF-MY-APP';

$process = new SSH(
    "ssh $target 'bash -se' << \\$delimiter".PHP_EOL
        .'set -e'.PHP_EOL
        .$command.PHP_EOL
        .$delimiter
);

结果是ThreadModel.getTableName()返回&#34; posts&#34;而不是&#34;线程&#34;。

我尝试了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; } Object.create(...),但两者似乎都没有做出深刻的复制。

JSFIDDLE:http://jsfiddle.net/dirkpostma/Lvc0u55v/3989/

我在这里做错了什么?

2 个答案:

答案 0 :(得分:2)

问题在于,使用Object.create进行此设置,您可以使用存储在同一公共闭包(BaseModel函数)中的tableName变量来生成服务。简而言之,init方法会修改相同的本地tableName变量。

你可以这样解决:

function BaseModel() {

  var service = {
    init: init,
    getTableName: getTableName
  };

  return service;

  function getTableName() {
    return this._tableName;
  }

  function init(theTableName) {
    this._tableName = theTableName;
  }
}

请注意,getTableNameinit方法现在可以使用this._tableNameTableModel个实例之间不共享的实例属性PostModel

演示: {{3}}

答案 1 :(得分:0)

@dfsq已经很好地解释并给出了一个简单的解决方案。我把这个问题放在这里。

在您的代码BaseModel中创建一个新对象,其原型是init函数的返回值。在这些子模型中,tableName方法会在BaseModel函数的本地范围内修改tableName。如果您将this.tableName替换为init,那将按预期工作:getTableNametableName方法实际上将修改/调用service ThreadModel属性PostModelvar 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"; } 函数中的变量。但它看起来很复杂。

在您的情况下,我想建议以下服务继承解决方案,这将更清楚。有an other post可能很有趣。

QueryInterface
_AddRef
_Release

JSFiddle:http://jsfiddle.net/Lvc0u55v/3993/