javascript 告诉 AngularJs 通过依赖注入返回一个新实例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13604655/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Tell AngularJs to return a new instance via Dependency Injection
提问by ?ukaszBachman
The use case is simple: I have two controllers sharing the same dependency MyService
. This service is holding some state, lets sat myVariable
. If I set it from ControllerOne
, then it will be also spotted by ControllerTwo
.
用例很简单:我有两个共享相同依赖项的控制器MyService
。此服务正在保持某种状态,让我们坐下myVariable
。如果我将它设置为 from ControllerOne
,那么它也会被ControllerTwo
.
What I want is for each controller to have it's own instance of MyService
, so that myVariable
can be changed by each Controller without affecting the other.
我想要的是每个控制器都有自己的 实例MyService
,这样myVariable
每个控制器都可以更改它而不会影响另一个。
To put it in another words - I want new instanceto be returned by Dependency Injection, rather than singleton.
换句话说 - 我希望新实例由依赖注入返回,而不是单例。
采纳答案by Ben Lesh
Not as directly has you might hope. Service instances are created the first time they're retrieved by the injector and maintained by the injector... in other words, they're always singletons. The magic happens in here, particularly look at the provider
function, which puts the provider instance in the providerCache object.
不像你希望的那样直接。服务实例在它们第一次被注入器检索并由注入器维护时被创建……换句话说,它们总是单例的。神奇发生在这里,特别是看看provider
函数,它将提供者实例放在 providerCache 对象中。
But don't lose hope, you could just as easily add constructors for whatever it is you want to share in a Service, if you so chose:
但是不要失去希望,您可以轻松地为您想要在服务中共享的任何内容添加构造函数,如果您选择:
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
});
EDIT: as the OP pointed out, there is also the $injector.instantiate, which you can use to call JavaScript constructors outside of your controller. I'm not sure what the implications are of the testability here, but it does give you another way to inject code that will construct a new object for you.
编辑:正如 OP 所指出的,还有$injector.instantiate,您可以使用它在控制器之外调用 JavaScript 构造函数。我不确定这里的可测试性的含义是什么,但它确实为您提供了另一种注入代码的方法,该代码将为您构造一个新对象。
回答by karlgold
There are plenty of general options for modularizing JavaScript code, but if you want to do something that relies solely on AngularJS, this pattern works:
有很多模块化 JavaScript 代码的通用选项,但如果你想做一些完全依赖 AngularJS 的事情,这个模式可以工作:
1) First define the class that you want to inject multiple times:
1)首先定义要多次注入的类:
function MyClass() {
// ...
}
MyClass.prototype.memberMethod = function() {
// ...
}
2) Next, make the constructor available as a constant:
2) 接下来,使构造函数可用作常量:
angular.module('myModule').constant('MyClass', MyClass);
3) Finally, use the factory pattern to create named, injectable instances of the class:
3) 最后,使用工厂模式创建类的命名的、可注入的实例:
angular.module('myOtherModule', ['myModule']).factory('instanceOfMyClass', [
'MyClass',
function(MyClass) { return new MyClass(); }
]);