22

用例很简单:我有两个控制器共享相同的依赖项MyService。该服务处于某种状态,让我们坐下myVariable。如果我从 设置它ControllerOne,那么它也会被ControllerTwo.

我想要的是每个控制器都有它自己的实例MyService,这样myVariable每个控制器都可以更改它而不影响另一个。

换句话说 - 我希望新实例由依赖注入返回,而不是 singleton

4

2 回答 2

22

不像你希望的那样直接。服务实例是在第一次被注入器检索并由注入器维护时创建的……换句话说,它们总是单例的。神奇的地方发生在这里,特别是看看这个provider函数,它将提供者实例放在 providerCache 对象中。

但是不要失去希望,如果您选择了,您可以轻松地为要在服务中共享的任何内容添加构造函数:

app.factory('myService', [function() {
     var i = 1;

     function Foo() {
        this.bar = "I'm Foo " + i++;
     };

     return {
          Foo: Foo
     };
}]);

app.controller('Ctrl1', function($scope, myService) {
  $scope.foo = new myService.Foo();
  console.log($scope.foo.bar) //I'm Foo 1
});

app.controller('Ctrl2', function($scope, myService) {
  $scope.foo = new myService.Foo();
  console.log($scope.foo.bar) //I'm Foo 2
});

编辑:正如 OP 所指出的,还有$injector.instantiate,您可以使用它在控制器之外调用 JavaScript 构造函数。我不确定这里的可测试性意味着什么,但它确实为您提供了另一种注入代码的方法,该代码将为您构建一个新对象。

于 2012-11-28T16:59:57.290 回答
3

模块化 JavaScript 代码有很多通用选项,但如果你想做一些完全依赖 AngularJS 的事情,这种模式可以工作:

1)首先定义要多次注入的类:

function MyClass() {
  // ...
}

MyClass.prototype.memberMethod = function() {
  // ...
}

2) 接下来,使构造函数可用作常量:

angular.module('myModule').constant('MyClass', MyClass);

3) 最后,使用工厂模式创建类的命名、可注入实例:

angular.module('myOtherModule', ['myModule']).factory('instanceOfMyClass', [
   'MyClass', 
   function(MyClass) { return new MyClass(); }
]);
于 2015-02-04T23:38:09.447 回答