[轉載]AngularJS之Factory vs Service vs Provider

http://www.oschina.net/translate/angularjs-factory-vs-service-vs-provider

http://tylermcginnis.com/angularjs-factory-vs-service-vs-provider/

要注意的文章中,app.provider(...)里的代碼有點出處,之后作者改過,但是轉載的網站上圖片上沒有改掉,應該是

 //Going to set this property on the config function belowthis.thingFromConfig = '';

-------------------------------------------------------

當你初試 Angular 時,很自然地就會往 controller 和 scope 里堆滿不必要的邏輯。一定要早點意識到,controller 這一層應該很薄;也就是說,應用里大部分的業務邏輯和持久化數據都應該放在 service 里。我每天都會在 Stack Overflow 上看到幾個同類的問題,關于如何在 controller 里保存持久化數據。這就不是 controller 該干的事。出于內存性能的考慮,controller 只在需要的時候才會初始化,一旦不需要就會被拋棄。因此,每次當你切換或刷新頁面的時候,Angular 會清空當前的 controller。與此同時,service 可以用來永久保存應用的數據,并且這些數據可以在不同的 controller 之間使用。

Angular 提供了3種方法來創建并注冊我們自己的 service。

  1. Factory

  2. Service

  3. Provider

如果你是“太長的不看”

1) 用? Factory 就是創建一個對象,為它添加屬性,然后把這個對象返回出來。你把 service 傳進 controller 之后,在 controller 里這個對象里的屬性就可以通過 factory 使用了。

FactoryExample1

2) Service? 是用"new"關鍵字實例化的。因此,你應該給"this"添加屬性,然后 service 返回"this"。你把 service 傳進 controller 之后,在controller里 "this" 上的屬性就可以通過 service 來使用了。

ServiceExample2

3) Providers ?是唯一一種你可以傳進 .config() 函數的 service。當你想要在 service 對象啟用之前,先進行模塊范圍的配置,那就應該用 provider。

ProviderExample3

詳細解釋(對于不是“太長不看”的讀者)

為了準確表現出 Factory、Service 和 Provider 之間的差別,下面我們用 3 種不同的方式來構建同一個服務。這個服務會用到 iTunes API 以及使用 $q 的 promise。

1) Factory

Factory 是創建和配置服務最常見的方式。除了“快速瀏覽”之外,其實沒有什么要補充的。只需創建一個對象,為它添加屬性,然后返回這個對象就可以了。當你把 factory 傳進 controller 中,對象的這些屬性就可以通過 factory 訪問。更詳細的例子如下:

首先創建一個對象,然后返回這個對象,如下。

factory1-4

現在如果我們把"myFactory"傳進 controller 里,附加在 "service" 上的任何屬性都可以訪問到了。

現在讓我們向回調函數中添加一些“private” 變量。當然 controller中是無法直接訪問這些變量的,不過我們最終還是會在“service”中設置setter和個getter 方法,以便必要時修改這些“private”變量。

factory4-5

你可能注意到了,我們沒有將變量/函數加到“service”中。我們只是簡單的創建他們以便之后的使用和修改。

  • ?baseUrl 是iTunes API要求的根URL

  • ?_artist 是我們想要查找的藝術家

  • _finalUrl 是最終的權限定URL,即我們調用iTunes的入口

  • makeUrl 是一個創建并返回友好的iTunesURL的函數

既然我們的幫手/私有變量和函數放在的合適的位置,那么讓我們向“service”對象中添加一些屬性。無論我們向”service“中添加什么, 我們都能在任意一個我們傳遞進‘myFactory’ 的controller中使用。

我們來創建setArtist和getArtist方法來簡單的返回或設置artist。同樣創建一個方法使用我們創 建的URL來調用iTunes API。這個方法將返回一個從iTunes API獲取數據后便會滿足的promise。如果你對Angular的promise接觸不多,我強烈推薦你深入的學習一下它。

  • setArtist 接受一個artist并且允許你設置artist

  • getArtist 返回artist

  • callItunes 首先調用makeUrl()方法以便構建$http請求使用的URL。然后它會設置promise對象,讓$http請求我們最終的URL, 再然后呢,因為$http返回一個promise,所以我們可以在請求后調用.success或.error。最后我們可以通過iTunes的數據來解析 我們的promise,或者直接‘There was an error’來拒絕它。

factory6
?

現在我們的factory完成了。我們可以將"myFactory"注入到任意controller中了,然后就可以調用我們添加到service對象中的方法了(setArtist,getArtist,和callItunes)。

factory2-7

在上面的controller中,我們注入了‘myFactory’ service對象。然后我們設置$scope 對象的屬性。上面唯一棘手的代碼是處理promise。因為callItunes返回一個promise對象,一旦我們的promise滿足了,我們可以 調用.then()方法以及設置$scope.data.artistData。你會注意到我們的controller是非常的“瘦”。因為我們所有的邏 輯和持久化數據都存放在了service中而不是controller中。

2) Service

當我們創建一個Service時,我們所知道的最重要事可能就是Service通過new關鍵字實例化對象。這應該可 以使熟悉JavaScript的人了解到了這段代碼的作用。但對于那些JS背景有限,或者不太熟悉new關鍵字的作用的人來說可能有點困難。那就讓我們來 重溫一下JavaScript的基本功能,以便幫助我們了解Service究竟做了什么。

讓我們先定義一個函數,然后通過new關鍵字來調用它,看看當解釋器遇到了new關鍵字的時候做了些什么工作,以便幫助我們了解使用new關鍵字來實例化一個函數時究竟有什么變化。這個的最終結果應該和Service是一樣的。

首先,讓我們定義一個構造器。

personConstructor-8

這個一個典型的JavaScript式的構造方法。現在,只要我們使用new關鍵字來調用Person函數,就會將'this'關鍵字綁定到新創建的對象上。

接下來,讓我們給Person的prototype對象添加一個方法,這個方法對所有Person ‘類’的實例都是可用的。

person.prototype-9

現在,由于我們往prototype上添加了一個sayName方法,所以所有的Person實例都可以調用這個方法,并且輸出對應實例的name值。

既然我們已經有了一個Person的構造器,并在在其prototype上定義了一個sayName方法,那就讓我們去創建一個Person的實例,并調用這個sayName方法。

personInstance-10

接下來,我們把創建Person構造器、往其prototype上添加方法、創建一個Person實例,并調用sayName方法的代碼寫在一塊,如下所示:

PersonCode-11

現在,讓我們看一下當我們在JavaScript中使用new關鍵字的時候究竟發生了什么。首先你應該已經注意到的 是,當我們在例子中使用了new關鍵字之后,我們可以通過'tyler'來調用方法(sayName),看上去好像tyler是一個對象——那是因為它確 實成了一個對象。所以,我們知道的第一件事就是我們的Person構造器返回了一個對象(object)。其次,我們知道,由于我們的sayName方法 是定義在Person的prototype上,而不是直接定義在Person的實例上的,所以Person函數返回的對象(tyler)一定是由于未找到 sayName方法,進而去prototype尋找sayName方法的。用更通俗的話來說,當我們調用tyler.sayName()時,JS解釋器 說,“好吧,我先去我們剛創建的'tyler'對象上查找sayName方法,然后調用它。等一下,我沒有在它上面找到sayName方法——我只看到了 name和age,那讓我去prototype找一下吧。沒錯,它在prototype上,那就讓我調用它吧”。

下面的代碼演示了在JavaScript中使用new關鍵之后所做的事。它是上面這一段文字的一個基本的代碼示例。我已經把從JS解釋器的角度來看整個過程的代碼寫在了注釋里。

PersonCommented-12

現在,既然我們了解了在JavaScript中new關鍵字是如何工作的,那么在Angular中創建一個Service也應該變得容易理解了。

在創建一個Service時,需要理解的最重要的一件事就是我們使用new關鍵字去實例化Service對象。結合我 們從上面的例子所了解到的知識,你應該已經意識到你可以將一些屬性和方法直接添加到this上,之后,在創建Service對象時,this會被作為返回 值返回。讓我們來看一下這種工作方式。

我們不用像之前Factory中的例子那樣創建一個對象,然后返回這個對象。因為我們使用了new關鍵字來調用,解釋器會創建一個對象,并關聯它的prototype對象,然后將該對象返回,而不用我們去做這些工作。

首先,讓我們創建我們的私有輔助函數。它應該看起來和我們在factory中所作的工作很類似。由于我已經在factory的例子中解釋過每一行代碼的含義了,所以我不會在這里多作解釋,如有疑惑,請再次回味一下factory的例子。

ServiceBase-13

接下來,我們將要把可以從控制器中訪問的方法添加到‘this’上。

serviceservice-14

現在,和使用factory一樣,所有將myService作為參數傳入的控制器都可以訪問到setArtist, getArtist, 和callItunes方法。下面是傳入了myService的控制器(基本上和factory的控制器一樣)。
ServiceController-15

正如我之前提到的那樣,一旦你了解了new關鍵字的作用,你就會知道在Angular中,Services和Factories幾乎一樣。

3) Provider

要記住的關于Provider的最重要的事情是,它們是你可以傳遞到應用程序的app.config部分唯一的服務。 如果你需要在你的服務對象可以在你的應用程序之外任何地方都可用之前改變它的某些部分,這是非常重要的。雖然Services/Factories很相 似,但也有一些差異,我們將會討論它們。

首先,我們用與我們建立Service 和 Factory類似的方式來建立我們的Provider。下面的變量是我們的'私人'和輔助功能。

ProviderBase-16

*同樣地,如果上面的代碼的任何部分令你糾結,請看下 Factory 部分,在那里我更詳細地解釋了這些代碼的作用。

必須要注意的一點是只有這些變量和函數是可以在我們的app.config函數中訪問的。這曾一度使我感到困惑,所以 你最好也要知道這點不同之處。你可以把Provider想象成由兩部分組成。第一部分的變量和函數是可以在app.config函數中訪問的,因此你可以 在它們被其他地方訪問到之前來修改它們(如上所示)。第二部分(如下所示)?的變量和函數是可以在任何傳入了’myProvider‘的控制器中進行訪問 的。

當你使用Provider創建一個service時,唯一的可以在你的控制器中訪問的屬性和方法是通過$get()函 數返回內容。下面的代碼將$get方法寫在了’this‘(最終會被函數返回)上。現在,$get函數會返回所有我們希望在控制器中進行訪問的方法和屬 性。下面是代碼示例:

provider$get-17

現在,Provider的完整代碼如下所示:

ProviderService-18

現在,與我們的Factory和Service類似,setArtist, getArtist, 和callItunes可以在任何一個傳入了 myProvider 的控制器中訪問。下面是myProvider的控制器(幾乎和我們Factory/Service中的控制器一樣)。

ProviderCtrl-19

正如前面提到的那樣,使用Provider創建一個service的獨特之處是,你可以在Provider對象傳遞到應用程序的其他部分之前在app.config函數對其進行修改。讓我們來看一個對應的例子。

appconfig-20

現在你可以明白‘thingFromConfig’是怎么樣地在我們的provider中是空字符串,而當它出現在DOM中時,它將是'This sentence was set…’。

謝謝您的閱讀,我希望這有助于你能辨別在Angular中Factory, Service, 和 Provider之間的差異。

*要查看完整的代碼示例,看看運行中的代碼,可以自由地fork我的repo: https://github.com/tylermcginnis33/AngularService

轉載于:https://www.cnblogs.com/Benoly/p/4246209.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/257723.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/257723.shtml
英文地址,請注明出處:http://en.pswp.cn/news/257723.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C#學習筆記:預處理指令

C#和C/C一樣,也支持預處理指令,下面我們來看看C#中的預處理指令。 #region 代碼折疊功能,配合#endregion使用,如下: 點擊后如下: 條件預處理 條件預處理可以根據給出的條件決定最終進行編譯的代碼&#xff…

android sh 指令_Java/Android中實現Shell命令

有時候我們需要實現一個功能。不過這個功能用我們傳統的Java代碼實現起來會有一些困難,這時我們可以嘗試利用Shell命令來實現。你可以按照下面的代碼模塊來進行你想要實現的Shell命令(注:也不是所有的Shell命令都能用Java代碼來實現)。public class Main…

【數字信號處理】 第二章、時域中的離散時間信號

前言 學而時習之,不亦樂乎? ——《論語學而》 Is it not pleasant to learn with a constant perseverance and application? 。 第二章 時域中的離散時間信號 一、離散信號的基本定義 1、兩個基本類型 抽樣數據類型:即模擬信號通過定周期進行采樣…

開機流程與主引導分區(MBR)——鳥哥私房菜

在前篇隨筆中,已經談到了CMOS與BIOS,CMOS是記錄各項硬件參數(包括系統時間、設備的I/O地址、CPU的電壓和頻率等)且嵌入到主板上面的存儲器,BIOS是一個寫入到主板上的韌體(韌體是寫入到硬件上的一個軟件程序…

整車廠核心制造系統及數據流

轉載于:https://www.cnblogs.com/tallrain/p/MES_Auto_Core_System.html

ch12 GUI

《Head First Java 2nd Edition》 摘錄 JFrame 代表屏幕上的一個窗口,可以把 buttons, checkboxes, test fields 等等界面相關的東西置于其上。它可以有一個有菜單項的菜單條。無論在哪個平臺上,都有窗口圖標,最小化、最大化和關閉窗口的按鈕…

兩物體的相對速度公式_《百答相對論》連載(二十一)質疑狹義相對論速度的疊加公式...

狹義相對論部分:(21)質疑狹義相對論速度的疊加公式參考《相對論百問》第28頁 21相對論的速度疊加公式怎么寫?可以用速度疊加達到和超過光速嗎?在經典力學中,物體在力的作用下改變原有的速度遵守牛頓第二定律,物體失去了…

對于大規模機器學習的理解和認識

這篇文章,9分轉載轉述;很少有自己的見解; 首先先露怯:自己真正是去年開始接觸機器學習當中的深度學習當中的卷積神經網絡當中的前向預測部分; 不過,剛才看完了這里的討論,(知乎&…

ARM寄存器

ARM處理器模式 用戶模式(User):ARM處理器正常的程序執行狀態 快速中斷模式(FIQ):用于高速數據傳輸或通道處理 外部中斷模式(IRQ):用于通用的中斷處理 管理模式(Supervisor):操作系統使用的保護模式 數據訪問終止模式(Abort):當數據或指令預取終止時進入該模式,可用于虛擬存儲及…

修改shape數據 小數位數_【數據管理】Excel實用精華

點擊上方藍字關注星標★不迷路來源:從Excel小白到數據分析師這是一篇關于Excel中的小技巧但是都是精華,文中附有操作視屏簡單易學上手快噢!01添加數據有效性_名稱管理器數據有效性是對單元格或單元格區域輸入的數據從內容到數量上的限制。對于…

刪除win10自帶的軟件

第一步:開始→所有程序→WindowsPowershell→然后右鍵以管理員方式運行 全部應用: Get-AppxPackage | Remove-AppxPackage 計算器: Get-AppxPackage calculator | Remove-AppxPackage 地圖: Get-AppxPackage map | Remove-A…

ubuntu解壓zip文件亂碼問題

我的zip文件里的內容是有中文名,也有密碼,在網上找到幾種解決辦法只有一種可以,所以在這里記錄一下: 首先是安裝7zip來解壓,7zip的解決辦法在這里,但是無法解決我的問題,仍然有亂碼問題 最后是在…

ICMP:Internet控制報文協議

ICMP:Internet控制報文協議。是IP層的組成部分。傳遞差錯報文或其他信息。 ICMP報文被封裝在IP數據報內部:詳細格式例如以下所看到的:個字段含義例如以下:8位類型。表示該ICMP報文的含義,如目的不可達、超時、請求回顯…

貝葉斯優化python包_貝葉斯全局優化(LightGBM調參)

這里結合Kaggle比賽的一個數據集,記錄一下使用貝葉斯全局優化和高斯過程來尋找最佳參數的方法步驟。1.安裝貝葉斯全局優化庫從pip安裝最新版本pip install bayesian-optimization2.加載數據集import pandas as pdimport numpy as npfrom sklearn.model_selection im…

PL/SQL 語言 一

Declarea Varchar2(20);b Number(10);c Number(10);m Number(5);sname Varchar2(20);nozero Exception;Begina : 小明;Dbms_Output.Put_Line(a);b : 3;c : 0;/* 循環 */ /* m :50;Loop Exit When m<0;dbms_output.put_line(m);m : m-1;End Loop; *//* While m>0Loop…

OpenCV人臉檢測

由于光照、遮擋和傾斜等原因&#xff0c;部分人臉和眼睛并不能正確檢測。。 // 簡單的人臉檢測#include <iostream> #include <vector> #include <opencv2\opencv.hpp> #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgu…

分離圓環圖顯示百分比_Tableau制作圓環圖

Tableau圓環圖制作 聲明&#xff1a;本文內容來源拉勾教育數據分析訓練營&#xff0c; 封面圖片來源pexels網站圓環圖制作過程如下&#xff1a;建立餅圖2. 設置記錄平均值3. 在第二個字段的下拉菜單中選擇雙軸4. 點擊右側坐標軸&#xff0c;右鍵選擇同步軸&#xff08;同步軸指…

FLEX 布局

網頁布局&#xff08;layout&#xff09;是CSS的一個重點應用。 布局的傳統解決方案&#xff0c;基于盒狀模型&#xff0c;依賴 display屬性 position屬性 float屬性。它對于那些特殊布局非常不方便&#xff0c;比如&#xff0c;垂直居中就不容易實現。 2009年&#xff0c;W3…

SpiderMonkey-讓你的C++程序支持JavaScript腳本

譯序 有些網友對為什么D2JSP能執行JavaScript腳本程序感到奇怪&#xff0c;因此我翻譯了這篇文章&#xff0c;原文在這里。這篇教程手把手教你怎樣利用SpiderMonkey創建一個能執行JavaScript腳本的C程序&#xff0c;并讓JavaScript腳本操縱你的C程序的內部數據、操作。從這篇教…

Android 虛擬機學習總結Dalvik虛擬機介紹

1、Dalvik虛擬機與Java虛擬機的最顯著差別是它們分別具有不同的類文件格式以及指令集。Dalvik虛擬機使用的是dex&#xff08;Dalvik Executable&#xff09;格式的類文件&#xff0c;而Java虛擬機使用的是class格式的類文件。一個dex文件能夠包括若干個類。而一個class文件僅僅…