据我了解,当在工厂内部时,我返回一个被注入控制器的对象.在服务内部时,我正在处理使用的对象this而不返回任何内容.
我假设服务总是单例,并且每个控制器都会注入一个新的工厂对象.然而,事实证明,工厂对象也是单身人士?
用于演示的示例代码:
var factories = angular.module('app.factories', []);
var app = angular.module('app', ['ngResource', 'app.factories']);
factories.factory('User', function () {
return {
first: 'John',
last: 'Doe'
};
});
app.controller('ACtrl', function($scope, User) {
$scope.user = User;
});
app.controller('BCtrl', function($scope, User) {
$scope.user = User;
});
Run Code Online (Sandbox Code Playgroud)
当改变user.first的ACtrl事实证明,user.first在BCtrl也发生了变化,比如User是一个单身?
我的假设是在一个带有工厂的控制器中注入了一个新实例?
mat*_*4pl 600
所有角度服务都是单身人士:
文档(请参阅单项服务):https://docs.angularjs.org/guide/services
最后,重要的是要意识到所有Angular服务都是应用程序单例.这意味着每个注入器只有一个给定服务的实例.
基本上服务和工厂之间的区别如下:
app.service('myService', function() {
// service is just a constructor function
// that will be called with 'new'
this.sayHello = function(name) {
return "Hi " + name + "!";
};
});
app.factory('myFactory', function() {
// factory returns an object
// you can run some code before
return {
sayHello : function(name) {
return "Hi " + name + "!";
}
}
});
Run Code Online (Sandbox Code Playgroud)
查看有关$ offer的演示文稿:http://slides.wesalvaro.com/20121113/#/
这些幻灯片用于AngularJs的一次聚会:http://blog.angularjs.org/2012/11/more-angularjs-meetup-videos.html
Luc*_*cia 380
对我而言,当我意识到它们都以相同的方式工作时,就会产生启示:通过运行一次,存储它们获得的值,然后在通过依赖注入引用时咳嗽相同的存储值.
说我们有:
app.factory('a', fn);
app.service('b', fn);
app.provider('c', fn);
Run Code Online (Sandbox Code Playgroud)
三者之间的区别在于:
a存储的值来自于运行fn,换句话说:fn()b的存储值来自newING fn,换句话说:new fn()c存储的值来自首先通过newing 获取实例fn,然后运行$get实例的方法这意味着,有一些类似于角度内的缓存对象,每次注入的值只分配一次,当它们第一次注入时,其中:
cache.a = fn()
cache.b = new fn()
cache.c = (new fn()).$get()
Run Code Online (Sandbox Code Playgroud)
这就是我们this在服务中使用并定义this.$get提供者的原因.
希望这可以帮助.
Epo*_*okK 95
用factory/ service/ provider:
var myApp = angular.module('myApp', []);
//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
this.sayHello = function() {
return "Hello, World!"
};
});
//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
return {
sayHello: function() {
return "Hello, World!"
}
};
});
//provider style, full blown, configurable version
myApp.provider('helloWorld', function() {
// In the provider function, you cannot inject any
// service or factory. This can only be done at the
// "$get" method.
this.name = 'Default';
this.$get = function() {
var name = this.name;
return {
sayHello: function() {
return "Hello, " + name + "!"
}
}
};
this.setName = function(name) {
this.name = name;
};
});
//hey, we can configure a provider!
myApp.config(function(helloWorldProvider){
helloWorldProvider.setName('World');
});
function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {
$scope.hellos = [
helloWorld.sayHello(),
helloWorldFromFactory.sayHello(),
helloWorldFromService.sayHello()];
}?
Run Code Online (Sandbox Code Playgroud)
Jus*_*cha 57
还有一种方法可以返回构造函数,以便您可以在工厂中返回新的类,如下所示:
function MyObjectWithParam($rootScope, name) {
this.$rootScope = $rootScope;
this.name = name;
}
MyObjectWithParam.prototype.getText = function () {
return this.name;
};
App.factory('MyObjectWithParam', function ($injector) {
return function(name) {
return $injector.instantiate(MyObjectWithParam,{ name: name });
};
});
Run Code Online (Sandbox Code Playgroud)
所以你可以在一个使用MyObjectWithParam的控制器中做到这一点:
var obj = new MyObjectWithParam("hello"),
Run Code Online (Sandbox Code Playgroud)
请参阅此处的完整示例:http:
//plnkr.co/edit/GKnhIN?p = preview
在这里讨论了google网页:http://groups.google.com/forum/#! msg/angular / 56sdORWEoqg /
b8hdPskxZXsJ
小智 51
以下是主要差异:
句法: module.service( 'serviceName', function );
结果:将serviceName声明为可注入参数时,将为您提供传递给的函数的实例module.service.
用法:通过简单地向注入的函数引用附加()来共享对调用有用的实用程序函数非常有用.也可以与injectedArg.call( this )或类似的运行.
句法: module.factory( 'factoryName', function );
结果:当将factoryName声明为injectable参数时,将通过调用传递给的函数引用提供返回的值module.factory.
用法:用于返回一个'class'函数,然后可以用来创建实例.
还要检查AngularJS文档和stackoverflow上关于服务与工厂混淆的类似问题.
这是使用服务和工厂的示例.阅读更多关于AngularJS服务与工厂的信息.
Sut*_*bey 27
添加到第一个答案,我认为.service()适用于以更多面向对象的方式(C#/ Java)编写代码的人(使用此关键字并通过prototype/Constructor函数实例化对象).
工厂适用于编写代码的开发人员,这些代码对于javascript /功能编码风格更为自然.
看看angular.js里面的.service和.factory方法的源代码 - 在内部它们都调用了provider方法:
function provider(name, provider_) {
if (isFunction(provider_)) {
provider_ = providerInjector.instantiate(provider_);
}
if (!provider_.$get) {
throw Error('Provider ' + name + ' must define $get factory method.');
}
return providerCache[name + providerSuffix] = provider_;
}
function factory(name, factoryFn) { \
return provider(name, { $get: factoryFn });
}
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}
Run Code Online (Sandbox Code Playgroud)
bin*_*les 25
非常简单:
.service - 注册函数将作为构造函数调用(又名'newed')
.factory - 注册函数将被调用为一个简单的函数
两次都被调用,导致单个对象被注入到应用程序的其他组件中.
Lui*_*rez 20
所有提供商的工作方式相同.不同的方法service,factory,provider只是让你完成同样的事情在更少的代码.
PS还有value和constant.
从链开始到provider结束的每个特殊情况value都有一个额外的限制.因此,要在它们之间做出决定,你必须问问自己哪些让你用更少的代码完成你想要的东西.
这是一张图片,告诉你我的意思:
你可以在博客文章中找到细分和参考指南,我得到了这张图片:
Rud*_*lah 13
以下是服务与工厂的更多示例,这些示例可能有助于了解它们之间的差异.基本上,一个服务有"新..."调用它,它已经被实例化.工厂不会自动实例化.
这是一个具有单一方法的服务:
angular.service('Hello', function () {
this.sayHello = function () { /* ... */ };
});
Run Code Online (Sandbox Code Playgroud)
这是一个使用方法返回对象的工厂:
angular.factory('ClassFactory', function () {
return {
sayHello: function () { /* ... */ }
};
});
Run Code Online (Sandbox Code Playgroud)
返回数字列表的工厂:
angular.factory('NumberListFactory', function () {
return [1, 2, 3, 4, 5];
});
console.log(NumberListFactory);
Run Code Online (Sandbox Code Playgroud)
返回数字列表的服务:
angular.service('NumberLister', function () {
this.numbers = [1, 2, 3, 4, 5];
});
console.log(NumberLister.numbers);
Run Code Online (Sandbox Code Playgroud)
两种情况下的输出都是相同的,即数字列表.
在这个例子中,我们定义了一个CounterFactory,它递增或递减一个计数器,你可以获得当前计数或获得已创建的CounterFactory对象的数量:
angular.factory('CounterFactory', function () {
var number_of_counter_factories = 0; // class variable
return function () {
var count = 0; // instance variable
number_of_counter_factories += 1; // increment the class variable
// this method accesses the class variable
this.getNumberOfCounterFactories = function () {
return number_of_counter_factories;
};
this.inc = function () {
count += 1;
};
this.dec = function () {
count -= 1;
};
this.getCount = function () {
return count;
};
}
})
Run Code Online (Sandbox Code Playgroud)
我们使用它CounterFactory来创建多个计数器.我们可以访问类变量来查看创建了多少个计数器:
var people_counter;
var places_counter;
people_counter = new CounterFactory();
console.log('people', people_counter.getCount());
people_counter.inc();
console.log('people', people_counter.getCount());
console.log('counters', people_counter.getNumberOfCounterFactories());
places_counter = new CounterFactory();
console.log('places', places_counter.getCount());
console.log('counters', people_counter.getNumberOfCounterFactories());
console.log('counters', places_counter.getNumberOfCounterFactories());
Run Code Online (Sandbox Code Playgroud)
此代码的输出是:
people 0
people 1
counters 1
places 0
counters 2
counters 2
Run Code Online (Sandbox Code Playgroud)
Shi*_*ala 13
"工厂"和"服务"是角度进行DI(依赖注入)的不同方式.
因此,当我们使用"服务"定义DI时,如下面的代码所示.这将创建"Logger"对象的新GLOBAL实例,并将其注入函数.
app.service("Logger", Logger); // Injects a global object
Run Code Online (Sandbox Code Playgroud)
使用"工厂"定义DI时,它不会创建实例.它只是传递方法,后来消费者在内部必须为工厂调用对象实例.
app.factory("Customerfactory", CreateCustomer);
Run Code Online (Sandbox Code Playgroud)
下面是一个简单的图像,直观地显示了"服务"的DI过程与"工厂"的不同之处.

当我们想要根据场景创建不同类型的对象时,应该使用工厂.例如,取决于我们想要创建简单"客户"对象的场景,或者具有"地址"对象的"客户"或具有"电话"对象的"客户".以下是本段的详细说明
应该使用服务当我们注入实用程序或共享函数时,如Utility,Logger,Error handler等.
服务风格:( 可能是最简单的一种)返回实际的函数:用于共享实用函数,通过简单地将()附加到注入的函数引用来调用它.
AngularJS中的服务是一个单独的JavaScript对象,它包含一组函数
var myModule = angular.module("myModule", []);
myModule.value ("myValue" , "12345");
function MyService(myValue) {
this.doIt = function() {
console.log("done: " + myValue;
}
}
myModule.service("myService", MyService);
myModule.controller("MyController", function($scope, myService) {
myService.doIt();
});
Run Code Online (Sandbox Code Playgroud)
工厂风格:( 更多涉及但更复杂)返回函数的返回值:在java中实例化一个对象,如new Object().
工厂是一个创造价值的功能.当服务,控制器等需要从工厂注入的值时,工厂按需创建值.一旦创建,该值将重用于需要注入的所有服务,控制器等.
var myModule = angular.module("myModule", []);
myModule.value("numberValue", 999);
myModule.factory("myFactory", function(numberValue) {
return "a value: " + numberValue;
})
myModule.controller("MyController", function($scope, myFactory) {
console.log(myFactory);
});
Run Code Online (Sandbox Code Playgroud)
提供者样式:( 完整的,可配置的版本)返回函数的$ get函数的输出:Configurable.
AngularJS中的提供商是您可以创建的最灵活的工厂形式.您使用模块注册提供程序,就像使用服务或工厂一样,但使用provider()函数除外.
var myModule = angular.module("myModule", []);
myModule.provider("mySecondService", function() {
var provider = {};
var config = { configParam : "default" };
provider.doConfig = function(configParam) {
config.configParam = configParam;
}
provider.$get = function() {
var service = {};
service.doService = function() {
console.log("mySecondService: " + config.configParam);
}
return service;
}
return provider;
});
myModule.config( function( mySecondServiceProvider ) {
mySecondServiceProvider.doConfig("new config param");
});
myModule.controller("MyController", function($scope, mySecondService) {
$scope.whenButtonClicked = function() {
mySecondService.doIt();
}
});
Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body ng-controller="MyCtrl">
{{serviceOutput}}
<br/><br/>
{{factoryOutput}}
<br/><br/>
{{providerOutput}}
<script>
var app = angular.module( 'app', [] );
var MyFunc = function() {
this.name = "default name";
this.$get = function() {
this.name = "new name"
return "Hello from MyFunc.$get(). this.name = " + this.name;
};
return "Hello from MyFunc(). this.name = " + this.name;
};
// returns the actual function
app.service( 'myService', MyFunc );
// returns the function's return value
app.factory( 'myFactory', MyFunc );
// returns the output of the function's $get function
app.provider( 'myProv', MyFunc );
function MyCtrl( $scope, myService, myFactory, myProv ) {
$scope.serviceOutput = "myService = " + myService;
$scope.factoryOutput = "myFactory = " + myFactory;
$scope.providerOutput = "myProvider = " + myProv;
}
</script>
</body>
</html>Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<div ng-controller="MyCtrl">
{{hellos}}
</div>
<script>
var myApp = angular.module('myApp', []);
//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
this.sayHello = function() {
return "Hello, World!"
};
});
//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
return {
sayHello: function() {
return "Hello, World!"
}
};
});
//provider style, full blown, configurable version
myApp.provider('helloWorld', function() {
this.name = 'Default';
this.$get = function() {
var name = this.name;
return {
sayHello: function() {
return "Hello, " + name + "!"
}
}
};
this.setName = function(name) {
this.name = name;
};
});
//hey, we can configure a provider!
myApp.config(function(helloWorldProvider){
helloWorldProvider.setName('World');
});
function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {
$scope.hellos = [
helloWorld.sayHello(),
helloWorldFromFactory.sayHello(),
helloWorldFromService.sayHello()];
}
</script>
</body>
</html>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
263846 次 |
| 最近记录: |