这段时间对AngularJS十分感兴趣,留意到Angular中有两个特性:service and factory ,用法看起来都差不多一样的,不知道有什么异同。
<html ng-app="myApp"> <script id="others_angular_103" type="text/javascript" class="library" src="/js/sandbox/other/angular.min.js"></script> <head></head> <body ng-app="myApp"> <div ng-controller="HelloCtrl"> <p>{{fromService}}</p> <p>{{fromFactory}}</p> </div> <br /> <div ng-controller="GoodbyeCtrl"> <p>{{fromService}}</p> <p>{{fromFactory}}</p> </div> </body> </html>
var app = angular.module('myApp',[]); app.service('reverseService',function(){ this.reverse = function(text){ return text.split(" ").reverse().join(" "); } }); app.factory('testFactory', function(){ return { sayHello: function(text){ return "Factory says \"Hello " + text + "\""; }, sayGoodbye: function(text){ return "Factory says \"Goodbye " + text + "\""; } } }); app.service('testService', function(){ this.sayHello= function(text){ return "Service says \"Hello " + text + "\""; }; this.sayGoodbye = function(text){ return "Service says \"Goodbye " + text + "\""; }; }); function HelloCtrl($scope, testService, testFactory) { $scope.fromService = testService.sayHello("World"); $scope.fromFactory = testFactory.sayHello("World"); } function GoodbyeCtrl($scope, testService, testFactory) { $scope.fromService = testService.sayGoodbye("World"); $scope.fromFactory = testFactory.sayGoodbye("World"); }
用法几乎完全一样。但是 service 写起来更简单点,看起来更简洁一点。
但是这并不能说明两者的不同,再看看下面的代码 :
app.service('reverseService',function(){ this.reverse = function(text){ return text.split(" ").reverse().join(" "); } }); app.factory('testFactory',['$window', function(win){ return { sayHello: function(text){ win.alert('hello,I am factory!!') return "Factory says \"Hello " + text + "\""; }, sayGoodbye: function(text){ return "Factory says \"Goodbye " + text + "\""; } } }]);
factory 可以有自己的依赖,像上面的代码,factory 可以 注入 $window 服务来调用 win.alert("")。而且service 就不行了。
或者 :
app.factory('helloWorld', ['$rootScope','$http',function($rootScope, $http) { }]);
为了理解根本上的不同,可以扒一下源码来看看两个func的实现:
function provider(name, provider_) { if (isFunction(provider_) || isArray(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); }]); }
可以看到 factory 是对 provider的封装, 举个例子:
var app = angular.module('myApp',[],function($provide) { $provide.provider('age',{ start : 10 , $get : function() { return this.start + 10 ; } }); }); or : 添加注入器案例: var app = angular.module('myApp',[],function($provide) { $provide.provider('age',{ start : 10 , $get : ['$window',function(win) { win.alert('hi'); return this.start + 10 ; }] }); }); function HelloCtrl($scope,age){ $scope.myage = age; }provider 是通过 $get 来在应用中注入单例,使用时取到的age就是 $get 返回的结果 。
结论就是:factory 是封装且简化了provide的一个功能,返回对象 。
从源码看,service 就是小三, 是对 factory 进行 更上一层的封装。
function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); }
总结 : service 就是 调用了 $injector 注入器的 factory ,简化数据共享的实现!
service 和 factory 都是单例模式(单例模式是一种设计模式)
看案例代码:
app.service('Service', function(){ this.name = 'yeelone'; this.set = function(name){ this.name = name ; }; this.get = function(){ return this.name; }; }); function HelloCtrl($scope,Service){ $scope.name = Service.get(); Service.set('newName'); } function ByeCtrl($scope,Service){ $scope.name = Service.get(); } 输出结果 : yeelone newName
var app = angular.module('myApp',[]); app.factory('NameFactory',function(){ var name = 'init'; return { set : function(name){ this.name = name ; }, get : function(){ return this.name ; } }; } ); function HelloCtrl($scope,NameFactory){ NameFactory.set('yeelone'); $scope.name = NameFactory.get(); } function ByeCtrl($scope,NameFactory){ $scope.name2 = NameFactory.get(); }
service和factory可以 实现 controller 之间的数据共享!