iT邦幫忙

DAY 26
0

我在前端 ng 時系列 第 26

Service,Factory 傻傻分不清楚

網路上有很多 Service vs Factory 的文章,最常看到的說法是 Service 是用 new 來建立的,而 Factory 是回傳 return 定義的值。
然後後面附上一長串看的霧煞煞的解釋文。

WHAT!???

我看了很多解釋後,最後有點小心得。也用自己的文字解釋一下~


先寫簡單的寫 Factory 跟 Service 範例:
以下的 Factory 跟 Service Dependency Injection (DI) 注入後所取用行為都是一樣。
範例:http://plnkr.co/edit/4BaT54BytV65EYsQUijq

angular.module('myExample', [])
  .controller('myCtrl', function($scope, LuffyFactory, LuffyService) {
     // 一樣的取用方式
      console.log('LuffyFactory', LuffyFactory.word); // 我要成為海賊王
      console.log('LuffyService', LuffyService.word); // 一樣~
  });

// factory
angular.module('myExample')
  .factory('LuffyFactory', function () {
    var factory = { };
    factory.word = '我要成成海賊王!';
    return factory;
})

// service
angular.module('myExample')
  .service('LuffyService', function () {
    this.word = '我要成為海賊王!';
})

Factory 的行為很簡單,Controller 注入Factory 取得的物件就是被 factory object ({}) 包起來並且 return 的物件
也就是說,假如沒有被 { } 包起來值都不會被外面取得。
(p.s. 不一定要 return object, 任何 type 都可以)

可改寫上面的範例,

angular.module('myExample')
  .factory('LuffyFactory', function () {
    // 這裡可以放 private value,外面無法取得
    var value = “Hello, 我是 private 值”;
    return {
         word: '我要成成海賊王!';
    }
})

Service 是把東西存在 this 裡面,像是我們平常在製作 constructor 一樣。
以上範例假如寫成 constructor 就會是

function LuffyService () {
  this.word = '我要成為海賊王!';
}

AngularJS 在初始化的時候,會幫我們把 new LuffyService() 這個動作完成。
所以當 controller 要求注入 LuffyService 的時候,AngularJS 就會把已經 new 過的的 LuffyService 給 controller。

回顧一下上篇文章說的,
Provider 都是 singleton。
Provider 都是 singleton。
Provider 都是 singleton。(很重要,所以說三次)

沒錯,所以就算 Service 有 new 這個指令,可是其實也只是做一次而已。
每個要求注入 Service 的 components 拿到的都會是同一個 Service reference。
Factory 也是相同的情況,全部系統共用一個 Factory reference。

來個簡單的例子證明。
範例:http://plnkr.co/edit/PfAwdHbKpsfIF3Aywwgu
兩個 controllers 同時注入相同名稱的 Service 跟 Factory,會發現兩個 controllers 的 Service 跟 Factory 回傳的 ID 都會一樣。

我個人最常使用 Factory 跟 Service singleton 的特性來儲存共用資料,讓系統裡不同的 components 都可以修改取得相同的資料來源。

Provider:

來簡單的說明一下 Provider 跟 Factory 和 Service 的關係。
個人覺得 Mark Meyer 在 top 10 mistakes angularjs developers make 文章解說的很好。
把 code 借來並附上我的註解。

// factory  的底層就是回傳 provider 的 $get 裡的值 
function factory(name, factoryFn) {
     return provider(name, { $get: factoryFn });
}

// service  的底層就是在 factory 裡使用 $jnjector.instantiate 跟 construct 建立新物件
// ( $injector.instantiate 會做 new instance 的動作)
function service(name, constructor) {
     return factory(name, ['$injector',
          function($injector) {
               return $injector.instantiate(constructor);
          }]);
}

目前我都可以用 Factroy 跟 Service 來實作我想要的功能,先少使用 Provider。(大概一次吧)
所以 Provider 的使用方式我就跳過了...
有興趣的朋友推薦看 Chang Yuntai 大大寫的 「AngularJS Service, Factory, Provider 差別」好文!
或是參考下面的文章~

參考文章:
AngularJS Providers Documentation
StackOverFlow: service vs provider vs factory


上一篇
瞭解重要的 Providers
下一篇
AngularJS with 觸控裝置
系列文
我在前端 ng 時30

尚未有邦友留言

立即登入留言