什么是之间的差异Service,Provider并Factory在AngularJS?
dependency-injection angularjs angularjs-service angularjs-factory angularjs-provider
我有这样的服务:
angular.module('app').factory('ExampleService', function(){
this.f1 = function(world){
return 'Hello '+world;
}
return this;
})
Run Code Online (Sandbox Code Playgroud)
我想从JavaScript控制台测试它并调用f1()服务的功能.
我怎样才能做到这一点?
请在这里忍受我.我知道还有其他答案,例如: AngularJS:Service vs provider vs factory
但是,当你在工厂使用服务时,我仍然无法弄清楚.
据我所知,工厂通常用于创建可由多个控制器调用的"通用"功能:创建通用控制器功能
Angular文档似乎更喜欢工厂而不是服务.他们甚至在使用工厂时提到"服务",这更令人困惑!http://docs.angularjs.org/guide/dev_guide.services.creating_services
那么什么时候才能使用服务?
是否有可能通过服务完成或更容易完成的事情?
幕后有什么不同吗?性能/内存差异?
这是一个例子.除了声明的方法,它们看起来完全相同,我无法弄清楚为什么我会做一个与另一个.http://jsfiddle.net/uEpkE/
更新:从托马斯的回答看来,似乎暗示服务是为了更简单的逻辑和工厂用于更复杂的逻辑与私有方法,所以我更新了下面的小提琴代码,似乎两者都能够支持私人功能?
myApp.factory('fooFactory', function() {
var fooVar;
var addHi = function(foo){ fooVar = 'Hi '+foo; }
return {
setFoobar: function(foo){
addHi(foo);
},
getFoobar:function(){
return fooVar;
}
};
});
myApp.service('fooService', function() {
var fooVar;
var addHi = function(foo){ fooVar = 'Hi '+foo;}
this.setFoobar = function(foo){
addHi(foo);
}
this.getFoobar = function(){
return fooVar;
}
});
function MyCtrl($scope, fooService, fooFactory) {
fooFactory.setFoobar("fooFactory");
fooService.setFoobar("fooService");
//foobars = "Hi fooFactory, …Run Code Online (Sandbox Code Playgroud) 如何管理不同环境的配置变量/常量?
这可能是一个例子:
我的其他API可以访问localhost:7080/myapi/,但我的朋友在Git版本控制下使用相同的代码,在他的Tomcat上部署了API localhost:8099/hisapi/.
假设我们有这样的事情:
angular
.module('app', ['ngResource'])
.constant('API_END_POINT','<local_end_point>')
.factory('User', function($resource, API_END_POINT) {
return $resource(API_END_POINT + 'user');
});
Run Code Online (Sandbox Code Playgroud)
如何动态注入API端点的正确值,具体取决于环境?
在PHP中,我通常使用config.username.xml文件执行此类操作,将基本配置文件(config.xml)与用户名识别的本地环境配置文件合并.但我不知道如何在JavaScript中管理这种事情?
编辑2016年1月:由于这仍然备受关注.自从问这个我已经完成了一些AngularJS项目,并且对于那些我最常用的项目factory,构建了一个对象并在最后返回了对象.我下面的语句是仍然如此,但是.
编辑:我想,我终于明白了两者之间的主要区别,和我有一个代码示例演示.我也在想这个问题所提出的重复不同.重复的说,服务不是实例化,但如果你将其设置为我下面演示,它实际上是.服务可以被设置为是完全一样的工厂.我还将提供显示工厂故障服务的代码,这似乎没有其他答案.
如果我成立VaderService像这样(即服务):
var module = angular.module('MyApp.services', []);
module.service('VaderService', function() {
this.speak = function (name) {
return 'Join the dark side ' + name;
}
});
Run Code Online (Sandbox Code Playgroud)
然后在我的控制,我可以这样做:
module.controller('StarWarsController', function($scope, VaderService) {
$scope.luke = VaderService.speak('luke');
});
Run Code Online (Sandbox Code Playgroud)
通过服务,注入到控制器的VaderService被实例化,所以我可以调用VaderService.speak,但是,如果我将VaderService更改为module.factory,控制器中的代码将不再起作用,这是主要区别.随着工厂,VaderService注入到控制器不实例化,这就是为什么你需要设立一家工厂(见我的问题为例)返回一个对象.
但是,您可以设置在完全相同的方式服务,你可以建立一个工厂(IE有它返回一个对象)和服务的行为完全一样作为一个工厂
鉴于此信息,我认为没有理由使用工厂超过服务,服务可以做任何工厂可以做的更多.
下面原来的问题.
我知道这已经被问的时候加载,但我实在看不出工厂和服务之间的功能差异.我读过这个教程:http://blogs.clevertech.biz/startupblog/angularjs-factory-service-provider
它似乎给一个合理的很好的解释,但是,我设立了我的应用程序如下:
的index.html
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
<script src="lib/angular/angular.js"></script>
<script type="text/javascript" src="js/controllers.js"></script>
<script type="text/javascript" src="js/VaderService.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</head>
<body ng-app="MyApp">
<table ng-controller="StarWarsController">
<tbody>
<tr><td>{{luke}}</td></tr>
</tbody>
</table> …Run Code Online (Sandbox Code Playgroud) 我正在寻找如何绑定到AngularJS中的服务属性的最佳实践.
我已经通过多个示例来了解如何绑定到使用AngularJS创建的服务中的属性.
下面我有两个如何绑定到服务中的属性的示例; 他们都工作.第一个示例使用基本绑定,第二个示例使用$ scope.$ watch绑定到服务属性
在绑定到服务中的属性时,这些示例中的任何一个都是首选的,还是有其他我不知道的选项会被推荐?
这些示例的前提是服务应每5秒更新其属性"lastUpdated"和"calls".更新服务属性后,视图应反映这些更改.这两个例子都成功地运作了 我想知道是否有更好的方法.
基本绑定
可以在此处查看和运行以下代码:http://plnkr.co/edit/d3c16z
<html>
<body ng-app="ServiceNotification" >
<div ng-controller="TimerCtrl1" style="border-style:dotted">
TimerCtrl1 <br/>
Last Updated: {{timerData.lastUpdated}}<br/>
Last Updated: {{timerData.calls}}<br/>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
<script type="text/javascript">
var app = angular.module("ServiceNotification", []);
function TimerCtrl1($scope, Timer) {
$scope.timerData = Timer.data;
};
app.factory("Timer", function ($timeout) {
var data = { lastUpdated: new Date(), calls: 0 };
var updateTimer = function () {
data.lastUpdated = new Date();
data.calls += 1;
console.log("updateTimer: " + data.lastUpdated);
$timeout(updateTimer, 5000); …Run Code Online (Sandbox Code Playgroud) data-binding angularjs angularjs-service angularjs-controller
我写了一个AngularJS服务,我想对它进行单元测试.
angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).
factory('myService', function ($http, fooService, barService) {
this.something = function() {
// Do something with the injected services
};
return this;
});
Run Code Online (Sandbox Code Playgroud)
我的app.js文件已注册:
angular
.module('myApp', ['fooServiceProvider','barServiceProvider','myServiceProvider']
)
Run Code Online (Sandbox Code Playgroud)
我可以测试DI是这样工作的:
describe("Using the DI framework", function() {
beforeEach(module('fooServiceProvider'));
beforeEach(module('barServiceProvider'));
beforeEach(module('myServiceProvder'));
var service;
beforeEach(inject(function(fooService, barService, myService) {
service=myService;
}));
it("can be instantiated", function() {
expect(service).not.toBeNull();
});
});
Run Code Online (Sandbox Code Playgroud)
这证明了服务可以由DI框架创建,但是接下来我想对服务进行单元测试,这意味着模拟注入的对象.
我该怎么做呢?
我已经尝试将模拟对象放在模块中,例如
beforeEach(module(mockNavigationService));
Run Code Online (Sandbox Code Playgroud)
并将服务定义重写为:
function MyService(http, fooService, barService) {
this.somthing = function() {
// Do something with the injected services
};
});
angular.module('myServiceProvider', …Run Code Online (Sandbox Code Playgroud) 这是我使用angularjs的演示,用于创建服务文件,以及向控制器添加服务.
我的演示有两个问题:
<script src="HomeController.js">在<script src="MyService.js">我收到此错误之前,错误:[ng:areq]参数'HomeController'不是函数,未定义
<script src="MyService.js">之前<script src="HomeController.js">收到以下错误,错误:[$ injector:unpr]未知提供者:MyServiceProvider < - MyService
我的来源:
档案Index.html:
<!DOCTYPE html>
<html >
<head lang="en">…</head>
<body ng-app="myApp">
…
<div ng-controller="HomeController">
<div ng-repeat="item in hello">{{item.id + item.name}}</div>
</div>
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-route.js"></script>
<!-- App libs -->
<script src="app/app.js"></script>
<script src="app/services/MyService.js"></script>
<script src="app/controllers/HomeController.js"></script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
档案HomeController.js:
(function(angular){
'use strict';
var myApp = angular.module('myApp',[]);
myApp.controller('HomeController',function($scope,MyService){
$scope.hello=[];
$scope.hello = MyService.getHello();
});
})(window.angular);
Run Code Online (Sandbox Code Playgroud)
档案MyService.js: …
我对angularJS很新.我正在寻找从RESTful API访问服务,但我没有任何想法.我怎样才能做到这一点?
我在多个页面中使用来自RESTful服务的一些数据.所以我正在使用棱角分明的工厂.因此,我需要从服务器获取一次数据,并且每次我使用该定义的服务获取数据.就像一个全局变量.这是样本:
var myApp = angular.module('myservices', []);
myApp.factory('myService', function($http) {
$http({method:"GET", url:"/my/url"}).success(function(result){
return result;
});
});
Run Code Online (Sandbox Code Playgroud)
在我的控制器中,我使用此服务:
function myFunction($scope, myService) {
$scope.data = myService;
console.log("data.name"+$scope.data.name);
}
Run Code Online (Sandbox Code Playgroud)
根据我的要求,它对我来说很好.但问题是,当我在我的网页上重新加载时,服务将再次被调用并请求服务器.如果在某些其他函数执行之间依赖于"已定义的服务",它会给出错误,例如"某事"是未定义的.所以我想在我的脚本中等待服务加载.我怎样才能做到这一点?无论如何在angularjs中有这样做吗?
angularjs ×10
javascript ×4
data-binding ×1
jasmine ×1
mocking ×1
rest ×1
restful-url ×1
wait ×1