Angular中的服務(wù)

在Angular中,服務(wù)的本質(zhì)是一些和控制器捆綁在一起的可替換的對(duì)象,通過這些對(duì)象提供了在應(yīng)用的整個(gè)生命周期都存有數(shù)據(jù)的方法,當(dāng)重載或刷新頁(yè)面時(shí),數(shù)據(jù)不會(huì)被清除,而且還與加載之前保持一致。

Angular服務(wù)介紹

在Angular中服務(wù)是一種單例對(duì)象。服務(wù)主要的功能是為實(shí)現(xiàn)應(yīng)用的功能提供數(shù)據(jù)和對(duì)象。它又可以分為內(nèi)置服務(wù)和自定義服務(wù)

內(nèi)置服務(wù)

Angular提供了很多內(nèi)置服務(wù),如$scope$http、$window$location等。

html:

<div ng-controller="MyController">
  <div>當(dāng)前的地址是: {{url}}</div>
  <button ng-click="onclick()">顯示地址</button>
</div>
var myapp = angular.module('MyApp', []);
myapp.controller('MyController', ['$scope', function($scope){
  $scope.onclick = function () {
    $scope.url = $location.absUrl();
  }
}])

$location服務(wù)除了包含absUrl()方法外,還有search()path()等方法。同時(shí)它還提供了$locationChangeStart$locationChangeSuccess方法

自定義服務(wù)

自定義服務(wù)有兩種方法,一是使用內(nèi)置的$provider服務(wù),另一種是調(diào)用模塊(Module)中的服務(wù)注冊(cè)方法,如factory、serviceconstantvalue等方法

html:

<div ng-controller="myCtrl">
  <div>服務(wù)返回的值:
    <span>{{info('name')}}</span>
    <span>{{info('sex')}}</span>
    <span>{{info('score')}}</span>
  </div>
</div>

javascript:

var app = angular.module('myApp', []);
  app.factory('$output', function () {
    var stu = {
      name: '張三',
      sex: '男',
      score: 60
    }
    return stu;
  });
  app.controller('myCtrl', ['$scope', '$output', function ($scope, $output) {
    $scope.info = function (n) {
      for (_n in $output) {
        if (_n == n) {
          return ($output[_n]);
        }
      }
    }
  }]);

創(chuàng)建Angular服務(wù)

在Angular中創(chuàng)建自定義服務(wù),只需要先構(gòu)建一個(gè)模塊(Module),然后在構(gòu)建過程中調(diào)用內(nèi)置的$provide服務(wù),通過該服務(wù)的工廠函數(shù)來創(chuàng)建屬于自己的Angular服務(wù)。除此之外,還可以調(diào)用模塊中的factory、service、constant、value方法來創(chuàng)建。

使用factory方法自定義服務(wù)

在Angular中,最常用的創(chuàng)建自定義服務(wù)的,就是factory方法了

app.factory(name, fn);

html:

<div ng-controller="MyController">
  <div>{{str('我是factory返回的內(nèi)容')}}</div>
  <div>{{name(1)}}</div>
</div>

javascript:

var myapp = angular.module('MyApp', []);
myapp.factory('outfun', function () {
  return {
    str: function (s) {
      return s;
    }
  }
});
myapp.factory('outarr', function () {
  return ['張三', '李四', '王五'];
});
myapp.controller('MyController', function ($scope, outfun, outarr) {
  $scope.str = function (n) {
    return outfun.str(n);
  }
  $scope.name = function (n) {
    return outarr[n];
  }
});

使用service方法自定義服務(wù)

使用service方法也可以自定義服務(wù),與factory不同的是,它可以接受一個(gè)構(gòu)造函數(shù)

app.service(name, fn)

其中,fn為構(gòu)造函數(shù),當(dāng)注入該服務(wù)時(shí),通過該函數(shù)并使用new關(guān)鍵字來實(shí)例化服務(wù)對(duì)象

html:

<div ng-controller="MyController">
  <div class="show">姓名: {{name}}</div>
  <div class="show">郵件: {{email}}</div>
  <div class="show">{{title}}</div>
  <button ng-click="say()">主題</button>
</div>

javascript:

var myapp = angular.module('MyApp', []);
  myapp.service('student', function () {
    this.name = 'Kaindy',
    this.email = 'kaindy7633@163.com',
    this.say = function () {
      return 'Hello, Angular!';
    }
  });
  myapp.controller('MyController', ['$scope', 'student', function ($scope, student){
    $scope.name = student.name;
    $scope.email = student.email;
    $scope.say = function () {
      $scope.title = student.say();
    }
  }]);

使用constant和value方法自定義服務(wù)

使用constantvalue方法創(chuàng)建服務(wù),常用于返回一個(gè)常量。

app.constant(name, value)
app.value(name, value)

html:

<div ng-controller="MyController">
  <div class="show">圖書ISBN號(hào): {{BOOK}}</div>
  <div class="show">美元兌換價(jià): {{USD}}</div>
</div>

javascript:

var myapp = angular.module('MyApp', []);
myapp.constant('$ISBN', {
    BOOK: '9898733238'
});
myapp.value('$RATE', {
    USD: 614.28
});
myapp.controller('MyController', function($scope, $ISBN, $RATE){
    var n = 600;
    angular.extend($RATE, {USD: n});
    $scope.BOOK = $ISBN.BOOK;
    $scope.USD = $RATE.USD;
})

管理服務(wù)的依賴

添加自定義服務(wù)依賴項(xiàng)方法

我們?cè)谧远x服務(wù)時(shí),會(huì)添加其他各類對(duì)象或服務(wù),有下面三種方式:

(1) 隱式聲明

在參數(shù)中直接調(diào)用,但這種方式在代碼壓縮時(shí)注入的對(duì)象可能會(huì)失效

app.factory('ServiceName', function(dep1, dep2) {})

(2) 調(diào)用$inject屬性

將需要注入的服務(wù)對(duì)象包裝成一個(gè)數(shù)組,作為$inject的屬性值,但這種方式效率很低

var sf = function(dep1, dep2) {};
sf.$inject = ['dep1', 'dep2'];
app.factory('ServieceName', sf);

(3) 顯式聲明

在創(chuàng)建服務(wù)的函數(shù)中,添加一個(gè)數(shù)組,在數(shù)組中按順序聲明需要注入的服務(wù)或?qū)ο竺Q,這種方式既高效也不會(huì)丟失代碼,推薦使用

app.factory('ServiceName', ['dep1', 'dep2', function(dep1, dep2) {} ])

html:

<div ng-controller="MyController">
  <div class="show">你選擇的是:{{result}}</div>
  <button ng-click="confirm('你真的要?jiǎng)h除這條記錄嗎?')">刪除</button>
</div>

javascript:

var myapp = angular.module('MyApp', []);

myapp.service('notify', ['$window', function ($win) {
  return function (msg) {
    return $win.confirm(msg) ? '確定' : '取消';
  }
}]);

myapp.controller('MyController', ['$scope', 'notify', function ($scope, notify) {
  $scope.confirm = function (msg) {
    $scope.result = notify(msg);
  }
}]);

嵌套注入服務(wù)

在Angular中,有時(shí)需要將一個(gè)自定義的服務(wù)注入到另一個(gè)自定義的服務(wù)中,形成嵌套注入的形式,通常只需要將被注入的服務(wù)作為內(nèi)置服務(wù),采用顯式聲明的方式注入即可

html:

<div ng-controller="MyController">
  <button ng-click="ask(false, '你輸入的內(nèi)容不正確')">提示框</button>
  <button ng-click="ask(true, '你真的要?jiǎng)h除這條記錄嗎?')">詢問框</button>
</div>

javascript:

var myapp = angular.module('MyApp', []);
  // 使用factory定義confirm服務(wù)
  myapp.factory('confirm', ['$window', function ($win) {
    return function (msg) {
      $win.confirm(msg);
    }
  }]);
  // 將confirm服務(wù)顯式的注入到notify服務(wù)中
  myapp.service('notify', ['$window', 'confirm', function ($win, con) {
    return function (t, msg) {
      return (t) ? con(msg) : $win.alert(msg);
    }
  }]);
  myapp.controller('MyController', ['$scope', 'notify', function ($scope, notify) {
    $scope.ask = function (t, msg) {
      notify(t, msg);
    }
  }])

添加服務(wù)的其他設(shè)置

創(chuàng)建好的服務(wù)一般比較復(fù)雜,如果后期需要修改,往往面臨很高的風(fēng)險(xiǎn),Angular為服務(wù)添加了一些設(shè)置項(xiàng),如裝飾器(decorator),可以在不修改原代碼的情況下為服務(wù)添加其他功能

服務(wù)的裝飾器

裝飾器(decorator)是Angular中內(nèi)置服務(wù)$provide所特有的一項(xiàng)設(shè)置函數(shù),通過它可以攔截服務(wù)在實(shí)例化時(shí)創(chuàng)建的一些功能,并對(duì)原有功能進(jìn)行優(yōu)化和替代。

$provide.decorator('ServiceName', Fn)
  • $provide表示注入后創(chuàng)建的服務(wù)對(duì)象
  • ServiceName表示需要攔截的服務(wù)名稱
  • Fn表示服務(wù)在實(shí)例化時(shí)調(diào)用的函數(shù),該函數(shù)在執(zhí)行時(shí)需要添加一個(gè)名為$delegate的參數(shù),該參數(shù)代表服務(wù)實(shí)例化后的對(duì)象,服務(wù)的新功能就是通過這個(gè)對(duì)象進(jìn)行擴(kuò)展和優(yōu)化的

示例代碼:

<div ng-controller="MyController">
  <div class="show">姓名: {{stu.name}}</div>
  <div class="show">郵件: {{stu.email}}</div>
  <div class="show">主題: {{stu.title}}</div>
</div>
var myapp = angular.module('MyApp', []);
  // 使用工廠函數(shù)factory定義student服務(wù)
  myapp.factory('student', function () {
    return {
      name: 'Kaindy',
      email: 'kaindy7633@gmail.com'
    }
  });
  // 使用$provider的裝飾器decorator為服務(wù)student擴(kuò)展一個(gè)title屬性
  myapp.config(function ($provide) {
    $provide.decorator('student', function ($delegate) {
      $delegate.title = 'Hello, Angular!';
      return $delegate;
    })
  });

  myapp.controller('MyController', function ($scope, student) {
    $scope.stu = student;
  });
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容