本教程使用AngularJS版本:1.5.3javascript
angularjs GitHub: https://github.com/angular/angular.js/
html
AngularJs下載地址:https://angularjs.org/java
用有過spring的人都知道,Spring的核心思想就是DI(依賴注入,Dependency Injection)和IOC(控制反轉 Invension of Controller),AngularJS的service其實就是用到了這裏的DI思想,那麼什麼叫作DI?所謂DI,就是指對象是被動接受依賴類而不是本身主動去找,換句話說就是指對象不是從容器中查找它依賴的類,而是在容器實例化對象的時候主動將它依賴的類注入給它。我我的的理解就是,你在實例化一個類時,它會自動去實例化它裏面所用到的其它實例。因此這就叫依賴注入。在Angular裏面,services做爲單例對象在須要到的時候被建立,只有在應用生命週期結束的時候(關閉瀏覽器)纔會被清除。而controllers在不須要的時候就會被銷燬了。git
AngualrJs中可用來注入的有三種類型,service、factory、provider,這三種寫法不樣,用法也都不同。其中,service只實例化一次,其實就是單例模式的思想。不管咱們在什麼地方注入咱們的service,將永遠使用同一個實例。因此對不少在controller層中的操做就能夠放到serivce層中去。AngularJS提供例如許多內在的服務,如:$http, $route, $window, $location等。每一個服務負責例如一個特定的任務,$http是用來建立AJAX調用,以得到服務器的數據。 $route用來定義路由信息等。內置的服務老是前綴$符號。angularjs
其中,三者的關係能夠當作是下圖:github
1、Service使用詳解
(1)定義spring
一個學用的service用法以下:後端
通常直接用this來操做數據、定義函數。數組
- app.service('myService', function() {
- var privateValue = "I am Private";
- this.variable = "This is public";
- this.getPrivate = function() { return privateValue;
- };
- });
(2)AngularJS中使用DI添加Service的三種方法
方式1(內聯註解,推薦使用):瀏覽器
- app.controller('myController', ['$scope', 'dateFilter', function ($scope, dateFilter) { }]);
方式2($inject註解):
- var MyController = function($scope, dateFilter) {}
- MyController.$inject = ['$scope', 'dateFilter'];
- someModule.controller('MyController', MyController);
方式3(隱式註解,不推薦使用):
- app.controller('myController', function ($scope, dateFilter) { });
推薦使用方式1的理由是:
寫法上比方法2更簡單明瞭
比方法3更可靠(因爲Javascript能夠被壓縮,AngularJS又是經過解析服務名稱找到對應Service的,所以Javascript壓縮以後AngularJS將沒法找到指定的Service,但字符串不會被壓縮,所以單獨以字符串指定Service的名稱能夠避免這個問題)
使用方式1或方式2的注意點:
因爲上述第二點緣由,AngularJS在編譯Html時,由$injector將數組中Service的名稱與方法體中的Service進行一一映射。這種映射關係必須遵照由AngularJS的約定:
數組中Service名稱的個數必須與方法體中Service名稱的個數一致
數組中Service的順序必須與方法體中Serivce的順序一致
(3)何時適合使用service()方法
service()方法很適合使用在功能控制比較多的service裏面
注意:須要使用.config()來配置service的時候不能使用service()方法
(4)service使用實例
一個完整實例:
- <!DOCTYPE html>
- <html lang="zh" ng-app="myApp">
- <head>
- <meta charset="UTF-8">
- <title>AngularJS學習</title>
- <script type="text/javascript" src="./1.5.3/angular.min.js"></script>
- </head>
- <body>
- <div ng-controller="myCtrl">
- <button ng-click="getPrivate()">按鈕一</button>
- <button ng-click="getPUbluc()">按鈕二</button>
- </div>
- <div ng-controller = "myCtrl2">
- </div>
- </body>
- <script type="text/javascript">
- var app = angular.module('myApp', []);
- app.controller('myCtrl', function($scope, myService) {
- $scope.getPrivate = function() {
- alert(myService.getPrivate());
- };
- $scope.getPUbluc = function() {
- alert(myService.variable);
- };
- });
- app.controller('myCtrl2', function($scope, myService) {
-
- });
- app.service('myService', function() {
- console.log('instance myService');
- var privateValue = "I am Private";
- this.variable = "This is public";
- this.getPrivate = function() {
- return privateValue;
- };
- });
- </script>
- </html>
效果以下:
另外,從這裏能夠看到兩個controller注入同一個service,可是最終只實例化了一次!
注意:seivce定義的服務不能在.config中使用!只有provider定義的才能夠
2、Factory使用詳解
Factory 通常就是建立一個對象,而後在對這個對象添加方法與數據,最後將些對象返回便可。而後注入到Controller層中便可。
使用實例:
- <!DOCTYPE html>
- <html lang="zh" ng-app="myApp">
- <head>
- <meta charset="UTF-8">
- <title>AngularJS學習</title>
- <script type="text/javascript" src="./1.5.3/angular.min.js"></script>
- </head>
- <body>
- <div ng-controller="myCtrl">
- <button ng-click="getPrivate()">按鈕一</button>
- <button ng-click="getPUbluc()">按鈕二</button>
- </div>
- <div ng-controller = "myCtrl2">
- </div>
- </body>
- <script type="text/javascript">
- var app = angular.module('myApp', []);
- app.controller('myCtrl', function($scope, myFactory) {
- $scope.getPrivate = function() {
- alert(myFactory.getPrivate());
- };
- $scope.getPUbluc = function() {
- alert(myFactory.variable);
- };
- });
- app.controller('myCtrl2', function($scope, myFactory) {
-
- });
- app.factory('myFactory', function() {
- console.log('instance myFactory');
- var factory = {};
- var privateValue = "I am Private";
- factory.variable = "This is public";
- factory.getPrivate = function() {
- return privateValue;
- };
- return factory;
- });
- </script>
- </html>
效果:
從下面能夠看到只實例化了一次,兩下Controller注入同一個factory,可是最終只實例化了一次!
記得必定要return一個Object對象,不然會報以下錯誤:
AngularJS中的Services:
3、provider使用詳解
$provide服務負責告訴Angular如何創造一個新的可注入的東西:即服務。服務會被叫作供應商的東西來定義,你可使用$provide來建立一個供應商。你須要使用$provide中的provider()方法來定義一個供應商,同時你也能夠經過要求$provide被注入到一個應用的config函數中來得到$provide服務。使用方法是返回一個$get函數,注意在config階段,只有provider能被注入。其它用法和service同樣。
下面是一個實例。
- <!DOCTYPE html>
- <html lang="zh" ng-app="myApp">
- <head>
- <meta charset="UTF-8">
- <title>AngularJS學習</title>
- <script type="text/javascript" src="./1.5.3/angular.min.js"></script>
- </head>
- <body>
- <div ng-controller="myCtrl1">
- <button ng-click = "onclick1()">請點擊我1</button>
- </div>
- <div ng-controller="myCtrl2">
- <button ng-click = "onclick2()">請點擊我2</button>
- </div>
- </body>
- <script type="text/javascript">
- var app = angular.module('myApp', []);
- app.controller('myCtrl1', function($scope, testProvider) {
- $scope.onclick1 = function() {
- testProvider("林炳文Evankaka");
- };
- });
- app.controller('myCtrl2', function($scope , testProvider) {
- $scope.onclick2 = function() {
- testProvider("我究竟是誰");
- };
- });
-
- app.provider('testProvider', function(){
- console.log('instance testProvider');
- var f = function(name) {
- alert("Hello, " + name);
- };
- this.$get = function(){ //必定要有!
- return f;
- };
- });
- </script>
- </html>
效果:
從如下能夠看到只實例化了一次:
- <!DOCTYPE html>
- <html lang="zh" ng-app="myApp">
-
- <head>
- <meta charset="UTF-8">
- <title>AngularJS學習</title>
- <script type="text/javascript" src="./1.5.3/angular.min.js"></script>
- </head>
-
- <body>
- <div ng-controller="myCtrl1">
- <button ng-click="onclick1()">請點擊我1</button>
- </div>
- <div ng-controller="myCtrl2">
- <button ng-click="onclick2()">請點擊我2</button>
- </div>
- </body>
- <script type="text/javascript">
- var app = angular.module('myApp', []);
- app.controller('myCtrl1', function($scope) {
- /* $scope.onclick1 = function() {
- test("林炳文Evankaka");
- };*/
- });
- app.controller('myCtrl2', function($scope) {
- /* $scope.onclick2 = function() {
- test("我究竟是誰");
- };*/
- });
- app.provider('test', function() {
- console.log('instance test');
- var f = function(name) {
- alert("Hello, " + name);
- };
- this.$get = function() { //必定要有!
- return f;
- };
- });
- /*app.config(function(testProvider) {
- testProvider('I am config');
- });*/
-
- app.config(function($provide) {
- $provide.provider('greeting', function() {
- this.$get = function() {
- return function(name) {
- alert("Hello," + name);
- };
- };
- });
- /* greetingProvider('ff');*/
- });
- </script>
-
- </html>
頁面刷新後,咱們發現即便不注入這個providrer,但也它也進行實例化了,而service/factory則是第一次注入時纔會初始化。而也這是爲何它能夠注入到config的一個緣由吧!
何時使用provider()方法
(1)當咱們但願在應用開始前對service進行配置的時候就須要使用到provider()。好比,咱們須要配置services在不一樣的部署環境裏面(開發,演示,生產)使用不一樣的後端處(2)理的時候就可使用到了
當咱們打算髮布開源provider()也是首選建立service的方法,這樣就可使用配置的方式來配置services而不是將配置數據硬編碼寫到代碼裏面。
4、Service、Factory、Provider三者區別
1
) 用 Factory 就是建立一個對象,爲它添加屬性,而後把這個對象返回出來。你把 service 傳進 controller 以後,在 controller 裏這個對象裏的屬性就能夠經過 factory 使用了。
2) Service 是用"new"關鍵字實例化的。所以,你應該給"this"添加屬性,而後 service 返回"this"。你把 service 傳進 controller 以後,在controller裏 "this" 上的屬性就能夠經過 service 來使用了。
3) Providers 是惟一一種你能夠傳進 .config() 函數的 service。當你想要在 service 對象啓用以前,先進行模塊範圍的配置,那就應該用 provider。
4)Factory/service是第一個注入時才實例化,而provider不是,它是在config以前就已實例 化好
同一函數三種不一樣寫法:
- <!DOCTYPE html>
- <html lang="zh" ng-app="myApp">
- <head>
- <meta charset="UTF-8">
- <title>AngularJS學習</title>
- <script type="text/javascript" src="./1.5.3/angular.min.js"></script>
- </head>
- <body>
- <div ng-controller="myCtrl">
- <p>{{ output1 }}</p>
- <p>{{ output2 }}</p>
- <p>{{ output3 }}</p>
- </div>
- <div ng-controller="myCtrl2">
- </div>
- </body>
- <script type="text/javascript">
- var app = angular.module('myApp', []);
- app.controller('myCtrl', function($scope,testService, testFactory, testProvider) {
- $scope.output1 = testService.lable;
- $scope.output2 = testFactory.lable();
- $scope.output3 = testProvider;
- });
- app.controller('myCtrl2', function($scope,testService, testFactory, testProvider) {
- });
- app.service('testService',function(){
- console.log('instance testService');
- this.lable = 'this is service';
- });
- app.factory('testFactory', function () {
- console.log('instance testFactory');
- return{
- lable: function(){
- return 'this is factory';
- }
- };
- });
- app.provider('testProvider', function(){
- console.log('instance testProvider');
- this.$get = function(){
- return 'this is provider';
- };
- });
- </script>
- </html>
看console的輸出,能夠知道都只實例 化了一次: