【问题标题】:Subclass factory in AngularJS with member variablesAngularJS中的子类工厂与成员变量
【发布时间】:2014-07-09 05:45:33
【问题描述】:

我有数十个 AngularJS 工厂,它们有很多共同点。所以我正在尝试创建一个基类并对其进行子类化。

但我注意到子类共享基类的成员变量。

我在http://jsbin.com/doxemoza/2/edit上做了一个例子,代码也贴在这里:

HTML:

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.3/angular.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body ng-app="demo" ng-controller="MainCtrl">
  <p>ChildService: {{value1}}</p>
  <p>AnotherChildService : {{value2}}</p>
</body>
</html>

JavaScript:

angular.module('demo', []);

var demo = angular.module('demo').controller('MainCtrl', function ($scope, ChildService, AnotherChildService) {
  $scope.value1 = ChildService.getPrivateVar();
  $scope.value2 = AnotherChildService.getPrivateVar();
});

var Base = function () {

  var Service = {};

  Service.privateVar = 0;

  Service.setPrivateVar = function (value) {
    Service.privateVar = value;
  }

  Service.getPrivateVar = function () {
    return Service.privateVar;
  }

  return Service;
};

demo.factory('BaseService', Base)


demo.factory('ChildService', function (BaseService) {
  var ChildService = Object.create(BaseService);
  ChildService.setPrivateVar(1);
  return ChildService;
});

demo.factory('AnotherChildService', function (BaseService) {
  var AnotherChildService = Object.create(BaseService);
  AnotherChildService.setPrivateVar(2);
  return AnotherChildService;
});

我的预期输出是:

ChildService: 1

AnotherChildService : 2

但是我得到了:

ChildService: 2

AnotherChildService : 2

我认为ChildServiceAnotherChildService 共享相同的privateVar,所以我得到了相同的值。

我应该如何更改代码以使它们使用 privateVar 的不同实例?

谢谢

【问题讨论】:

    标签: javascript angularjs oop


    【解决方案1】:

    我遇到了同样的问题,当我以这种方式声明我的 BaseService 时解决了:

    demo = angular.module('demo', []);
    
    demo.factory('BaseService', function(){
      return {
        privateVar: 0,
    
        setPrivateVar: function (value) {
          this.privateVar = value;
        },
    
        getPrivateVar: function () {
            return this.privateVar;
        }
      }
    });
    

    我的“子”服务和你的一样。一切正常。

    【讨论】:

    • 这确实有效。但是你或其他人能解释一下为什么会这样吗?它似乎确实在做同样的事情,但显然在内部工作方式略有不同。
    • 我还注意到直接设置privateVarChildService.privateVar = 5 也可以正常工作,只要您也像ChildService.privateVar 一样访问。也就是说,如果不使用 getter 和 setter,您的代码可以正常工作。
    【解决方案2】:

    我使用这样的东西:

    angular.module('app')
    .controller('ParentController', ['$scope', 'dataService', function ($scope, dataService) {
       //controller logic here
    }])
    .controller('ChildController', ['$scope', '$controller', 'SomeDataService', function ($scope, $controller, SomeDataService) {
    //extend your parentcontroller
        $scope.init = function () {
            //do something
        }
        angular.extend(this, $controller('ParentController', {
            $scope: $scope,
            dataService: SomeDataService
        }));
    }])
    .factory('BaseDataService', ['logger', function (logger) {
      var privateArray = [];
    
      return {
       publicFunction: function(){ return privateArray; },
       publicVar: "some var"
      }
    }])
    .factory('SomeDataService', ['BaseDataService', function (dataService) {
        var service = angular.extend({}, dataService);
        service.privateFunction = function () {
            //some code
        }
        service.privateVar= "some value";
        return service;
    }]);
    

    在这个例子中我把它们全部组合起来了。

    希望这会有所帮助。

    编辑:这使用了post中描述的混合模式

    【讨论】:

    • 那么关键是使用angular.extend?我已经尝试过了,但它也不起作用,请参阅:jsbin.com/qosibope/1/edit
    • 我也试过angular.copy 也不起作用
    • 我尝试了一些东西。 jsbin.com/qosibope/3/edit 当您直接访问变量时,它可以工作。
    • 我认为函数的使用对我的项目来说确实是必要的,否则我将不得不做大量的复制/粘贴,而失去了面向对象编程的好处
    • 我必须同意,这种行为有点奇怪......定义的函数在基本上下文中调用。以及子上下文中的变量。那并不是很有用...我在很多服务上都使用了这种抽象机制,但从未使用过作为私有变量设置器的函数。大多数时候我会覆盖函数和/或变量。
    猜你喜欢
    • 2015-03-12
    • 1970-01-01
    • 2015-09-19
    • 2016-07-12
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多