1. 程式人生 > >(11)AngularJS 1.X 之自定義服務

(11)AngularJS 1.X 之自定義服務

1.引言

      在本篇部落格中主要介紹一下如何自定義服務,為什麼要自定義服務?首先我們應該意識到:在開發的過程中,controller 這一層應該很薄;也就是說,應用裡大部分的業務邏輯 和持久化資料都應該放在 service裡。controller 中就不應該儲存持久化資料,出於記憶體效能的考慮,controller 只在需要 的時候才會初始化,一旦不需要就會被拋棄。因此,每次當你切換或重新整理頁面的時候, Angular 會清空當前的 controller。與此同時,service 可以用來永久儲存應用的資料, 並且這些資料可以在不同的 controller 之間使用。

      關於自定義服務有三種方法,三種方法分別為:

  • provider
  • factory
  • service

這三種方法建立自定義服務都有著自己的特點,我們以前說過:服務的型別有兩種,一種是具有供應商的服務,一種是不具備供應商的服務,通過Provider方法建立的服務是具有供應商的,因此我們可以將Provider建立的服務傳入config方法進行配置;而FactoryService方法建立的服務是不具備供應商概念的,FactoryService兩個方法建立服務也有細微的區別,接下來我們分別使用這三種方法建立自定義服務。

2.通過service方法自定義服務

      service方法定義的服務 是用new關鍵字例項化的。因此,我們可以直接給this

新增屬性,然後服務返回this。我們也可以將自定義的服務注入到我們的控制器中。使用service方法自定義服務也有兩種方式,一種是通過模組的service方法自定義服務,一種是通過$provide服務自定義服務。接下來我們就來看一下這兩種方法。

  • 重點說明service自定義服務是new一個函式物件(一定是物件)

2.1 使用模組service方法自定義服務

  • 自定義服務,服務名稱為$myService

        var app = angular.module('myApp',[]);
        app.service("$myService",function
(){
var _name="wpx"; this.getName=function(){ return _name; } })
  • 在控制區中注入我們的服務
        app.controller("firstController", function ($scope,$myService) {
            $scope.name=$myService.getName()
        })
  • html片段
<div ng-controller="firstController">{{name}}</div>
  • 執行結果

這裡寫圖片描述

2.2 使用$provide服務的service方法自定義服務

  • 自定義我們的服務:$myService
        var app = angular.module('myApp',[], function ($provide) {
            $provide.service("$myService", function () {
                var _name="wpx";
                this.getName= function () {
                    return _name;
                }
            })

        });
  • 將服務注入到控制器中
    app.controller("firstController", function ($scope,$myService) {
            $scope.name=$myService.getName()
        })
  • html 片段
    <div ng-controller="firstController">{{name}}</div>
  • 執行結果

這裡寫圖片描述

2.3 service自定義服務解釋

  • 首先我們注意到:service自定義的服務是一個函式。
  • service自定義的服務函式是可以注入其他服務的,比如我注入$http服務,可以這麼寫
//注入其他服務
app.service("$myService",function($http){

        })
  • service自定義的服務是new出來的,也就是說改服務的實現和函式類用法一樣,比如:
        function myClass() {

        }
        var a=new myClass();

3.通過factory方法自定義服務

      使用factory方法自定義服務也是有兩種方式,通過模組定義,通過$provide服務的factory方法定義服務,factory建立的服務和service方法定義的服務是有區別的,factory 方法直接把一個函式當成一個物件的$get方法,因此factory 建立的服務 是可以直接返回字串的。service自定義的服務就不可以直接返回字串),接下來我們就使用factory 方法自定義我們的服務

  • 重點說明factory自定義服務是是呼叫函式 ,然後返回一個物件,或者是資料

3.1 使用模組factory方法自定義服務

  • 自定義服務,服務名稱為:$myFactory1(返回字串)
    var app = angular.module('myApp',[]);
        app.factory("$myFactory1",function(){
            return "aaaa";
        })
  • 自定義服務,服務名稱為:$myFactory2(返回物件)
app.factory("$myFactory2",function(){
            var _name;
            function getName(){
                return _name;
            }
            function setName(name)
            {
                _name=name;
            }
            return {
                getName:getName,
                setName:setName
            }
        })
  • 將自定義服務注入到控制器

app.controller("firstController", function ($scope,$myFactory1,$myFactory2) {
            $scope.name=$myFactory1
            $myFactory2.setName("wpx");
})
app.controller("secondController", function ($scope,$myFactory2) {
            $scope.name=$myFactory2.getName()
        })
  • html片段
    <div ng-controller="firstController">{{name}}</div>
    <div ng-controller="secondController">{{name}}</div>
  • 執行結果

這裡寫圖片描述

3.2 使用服務factory方法自定義服務

      話不多少,直接上程式碼

        var app = angular.module('myApp',[], function ($provide) {
            $provide.factory("factoryName",function () {
                //服務程式碼
            })
        });

3.3 解釋factory方法自定義的服務

  • 第一點:factory的服務是當作方法來呼叫
  • 第二點:factory自定義服務也可以注入其他服務,比如:$http
app.factory("$myFactory1",function($http){
            //程式碼實現
            //記得return
        })
  • 第三點:服務是單例的,通過例項我們知道,服務可以在多個控制器之間傳遞資料(在控制器一中給服務新增資料,然後在控制器2中讀取資料)

4.通過provider方法自定義服務

      在前面我們說過provider方法定義的服務最大的區別在於具有供應商的概念,具有了供應商我們就可以通過config方法配置一些全域性的屬性。首先我們先使用provider定義一個簡單的服務。

4.1 provider定義簡單服務

  • 使用模組的provider定義一個服務(叫做mySelf
    var app = angular.module('myApp',[]);
        app.provider("$mySelf", function () {
            this.$get=function(){
                return {
                    message:"$mySelf"
                }
            }
        })
  • 使用$provide定義一個服務(叫做mySelf
        var app = angular.module('myApp',[], function ($provide) {
            $provide.provider("$mySelf", function () {
                this.$get=function(){
                    return {
                        message:"$mySelf"
                    }
                }
            })
        });
  • 將自定義服務注入到控制器
app.controller("firstController", function ($scope,$mySelf) {
            $scope.message=$mySelf.message

        })
  • html片段
    <div ng-controller="firstController">{{message}}</div>
  • 執行結果

這裡寫圖片描述

4.2 provider定義需要配置的服務

      剛剛我們說過:通過provider定義的服務會生成供應商,有供應商的服務可以通過模組的config方法進行配置,接下來我們來使用一下供應商。

  • 建立一個自定義的服務(該服務需要配置一個attr屬性)
        var app = angular.module('myApp',[]);
        app.provider("$mySelf", function () {
            //需要配置的屬性
            this.attr="";
            this.$get=function(){
                var that=this;
                var service={};
                var _attr="$mySelf.attr";
                service.getAttr=function(){
                    return _attr+"-----"+that.attr;
                }
                return service;
            }
        })
  • 通過供應商配置屬性(在服務的後面新增Provider就是供應商)
app.config(function ($mySelfProvider) {
            $mySelfProvider.attr="config.attr";
        })
  • 將服務注入到控制器中
app.controller("firstController", function ($scope,$mySelf) {
            $scope.attr=$mySelf.getAttr();

        })
  • html片段
<div ng-controller="firstController">{{attr}}</div>
  • 執行結果

這裡寫圖片描述

4.3 provider建立的服務需要注意的地方

  • 使用provider方法建立服務具有供應商
  • 我們可以通過config配置供應商的屬性
  • 使用provider自定義服務是如何建立的?首先我們看一下服務的定義
//首先我們new了一下,服務函式然後使用this.$get方法,將得到的結果注入到了控制器中,也就是說provider方法建立的服務其實是service方法和factory方法的一個組合使用。
app.provider("$mySelf", function () {
            //需要配置的屬性
            this.attr="";
            this.$get=function(){
                var that=this;
                var service={};
                var _attr="$mySelf.attr";
                service.getAttr=function(){
                    return _attr+"-----"+that.attr;
                }
                return service;
            }
        })
    *

5 使用供應商修改預設表示式符號

      前面我們說了,部分服務是具有供應商的,既然AngularJS提供了一些預設的服務,那麼就應該有一些預設的供應商,這裡我們就使用一下預設的供應商修改一下預設的表示式,預設表示式是{{表示式}},現在我們將其修改為#表示式#

5.1 使用$interpolateProvider供應商修改預設表示式服務

  • 使用config方法設定供應商
        var app = angular.module('myApp',[]);
        app.config(function ($interpolateProvider) {
            $interpolateProvider.startSymbol("#");
            $interpolateProvider.endSymbol("#");
        })
  • 使用新的表達數輸出資料
//控制器
app.controller("firstController", function ($scope) {
            $scope.attr="hello world";
})
//html片段
<div ng-controller="firstController">#attr#</div>
  • 執行結果

這裡寫圖片描述

6 服務注入,程式碼壓縮問題

      在使用服務的時候,不可避免的就會涉及到依賴注入的問題,如果服務的名稱過長,那麼我們多次使用服務程式碼的體積就會變得越來越大,所以我們在注入服務的時候可以給服務:起別名。利用非常短的別名來代替服務,接下來我們看一看如何注入我們的服務,以$scope服務為例:

app.controller("firstController",["$scope","$rootScope",function ($s,$rs) {
            $s.name="wpx";
            $rs.age="20";
        }])
  • html程式碼片段
<div ng-controller="firstController">{{name}}---{{age}}</div>
  • 執行結果

這裡寫圖片描述

  • 在上面的例子中,我們使用$s代替$scope$rs代替$rootScope,那麼在控制器中,我們就可以直接使用別名,這樣就會減少程式碼量
  • 只要是涉及服務注入的情況都可以使用這種方法進行程式碼壓縮。