AngularJS 中的 Factory、Service以及 Provider的區別

AngularJS 的供應商($provide)


$provide 服務負責告訴 AngularJS 如何建立一個新的可注入的東西: 即服務。javascript

服務會被叫作供應商的東西來定義, 能夠使用 $provide 來建立一個供應商。html

建立供應商的方法:java

  • 使用 $provide 中的 provider() 方法來定義一個供應商;segmentfault

  • 經過要求 $provide 被注入一個應用的 config 函數中來得到 $provide 服務;app

定義供應商的方法們


  • constantide

  • value函數

  • service測試

  • factorythis

  • providerspa

  • decorator

1. constant

定義常量的, 它定義的值不能被改變, 它能夠被注入到任何地方, 可是不能被裝飾器(decorator) 裝飾。

DEMO:

HTML 代碼:

<!DOCTYPE html>
<html lang="en">

<head>
    <title>demo</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
    <div ng-app="myApp">
        <div ng-controller="myController">

        </div>
    </div>
    <script src="js/angular.js">
    </script>
    <script src="js/service.js"></script>
</body>

</html>

JS 代碼:

var myApp = angular.module('myApp', [])
myApp.config(function($provide) {
    $provide.constant('movieTitle', '功夫瑜伽')
})
myApp.controller('myController', function(movieTitle) {
    console.log('movieTitle: ', movieTitle);
})

語法糖:

myApp.constant('movieTitle', '功夫瑜伽')

2. value

它能夠是 stringnumberfunction, 它和 constant 的不一樣之處在於, 它能夠被修改, 不能被注入到 config 中, 可是它能夠被 decorator 裝飾。

HTML 代碼:

<!DOCTYPE html>
<html lang="en">

<head>
    <title>demo</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
    <div ng-app="myApp">
        <div ng-controller="myController">

        </div>
    </div>
    <script src="js/angular.js">
    </script>
    <script src="js/service.js"></script>
</body>

</html>

JS 代碼:

var myApp = angular.module('myApp', [])

myApp.config(function($provide) {
    $provide.value('movieTitle', '功夫瑜伽')
})

myApp.controller('myController', function(movieTitle) {
    console.log('movieTitle: ', movieTitle);
})

語法糖:

myApp.value('movieTitle', '功夫瑜伽')

3. service

它是一個可注入的構造器, 在 AngularJS 中它是單例的, 用它在 Controller 中通訊或者共享數據都合適

var myApp = angular.module('myApp', [])

myApp.config(function($provide) {
    $provide.service('movie', function() {
        this.title = '功夫瑜伽'
    })
})

myApp.controller('myController', function(movie) {
    console.log('movieTitle: ', movie.title);
})

語法糖:

myApp.service('movie', function () {
    this.title = '功夫瑜伽'
})

注意:

service 裏面能夠不用返回東西, 由於 AngularJS 會調用 new 關鍵字來建立對象。可是返回一個自定義對象好像也不會有錯。

4. factory

它是一個可注入的 function, 它和 service 的區別就是: factory 是普通的 function, 而 service 是一個構造器(constructor), 這樣 AngularJS 在調用 service 時會用 new 關鍵字, 而調用 factory 時只是調用普通的 function, 因此 factory 能夠返回任何東西, 而 service 能夠不返回 (可查閱 new 關鍵字的做用)

var myApp = angular.module('myApp', [])

myApp.config(function($provide) {
    $provide.factory('movie', function() {
        return {
            title: '功夫瑜伽'
        }
    })
})

myApp.controller('myController', function(movie) {
    console.log('movieTitle: ', movie.title);
})

語法糖:

$provide.factory('movie', function() {
    return {
        title: '功夫瑜伽'
    }
})

注意:

factory 能夠返回任何東西, 它其實是一個只有 $get 方法的 provider

5. provider

provider 是他們的老大, 上面的幾乎(除了 constant) 都是 provider 的封裝, provider 必須有一個 $get 方法, 固然也能夠說 provider 是一個可配置的 factory

JS 代碼:

var myApp = angular.module('myApp', [])

myApp.provider('movie', function() {
    var version
    return {
        setVersion: function(value) {
            version = value
        },
        $get: function() {
            return {
                title: '功夫瑜伽 ' + version
            }
        }
    }
})

myApp.config(function(movieProvider) {
    movieProvider.setVersion('正在熱播')
})

myApp.controller('myController', function(movie) {
    console.log('movieTitle: ', movie.title);
})

注意:

  • 這裏 config 方法注入的是 movieProvider, config 方法中只能注入供應商(兩個例外是 $provide$injector),用駝峯命名法寫成 movieProvider, AngularJS 會自動幫你注入它的供應商。

  • movie 是一個供應商

6.decorator

decorator 不是 provider, 它是用來裝飾其它 provider 的, 它不能裝飾 constant(由於 constant 不是經過 provider() 方法建立的)。

JS 代碼:

var myApp = angular.module('myApp', [])

// myApp.value('movieTitle', '功夫瑜伽6')
myApp.config(function($provide) {
    $provide.value('movieTitle', '功夫瑜伽7')

    $provide.decorator('movieTitle', function($delegate) {
        return $delegate + ' - 測試'
    })
})

myApp.controller('myController', function(movieTitle) {
    console.log('movieTitle: ', movieTitle);
})

總結


  • 全部的供應商都只被實例化一次, 也就是說它們都是單例的

  • 除了 constant, 全部的供應商均可以被裝飾器(decorator)裝飾

  • value 就是一個簡單可注入的值

  • service 是一個可注入的構造器

  • factory 是一個可注入的方法

  • decorator 能夠修改或封裝其餘的供應商(除了 constant)

  • provider 是一個可配置的 factory

相關文章
相關標籤/搜索