目錄
什麼是提供者?
注入非類提供者
提供者和單例
總結
關於 Angular 2 組件、提供者、類、工廠和值的常見問題 (FAQ)
類和工廠在 Angular 2 中有什麼區別?
組件和提供者如何在 Angular 2 中交互?
值在 Angular 2 中的作用是什麼?
如何在 Angular 2 中綁定類?
在 Angular 2 的上下文中,API 是什麼?
如何在 Angular 2 中使用工廠?
如何在 Angular 2 中創建組件?
如何在 Angular 2 中使用提供者?
如何在 Angular 2 中創建服務?
如何在 Angular 2 中使用值?
首頁 web前端 js教程 Angular 2組件和提供商:類,工廠和價值觀

Angular 2組件和提供商:類,工廠和價值觀

Feb 15, 2025 pm 12:07 PM

Angular 2 Components and Providers: Classes, Factories & Values

核心要點

  • Angular 2 組件能夠使用提供者 (providers),提供者是一組可注入的對象,組件可以使用它們。提供者是 Angular 2 依賴注入 (DI) 系統的基礎。
  • 提供者可分為三種類型:類提供者、工廠提供者和值提供者。類提供者生成類的實例,工廠提供者生成指定函數的返回值,值提供者直接返回其值。
  • Angular 2 的 DI 系統允許註冊類、函數或值(稱為提供者),解決提供者之間的依賴關係,使提供者的結果可在代碼中使用,並維護注入器的層次結構。
  • Angular 的注入器只創建一次類提供者的實例,並將其緩存,只要使用相同的提供者,後續每次注入都會收到相同的實例。此功能使您可以靈活地控制任何一個提供者生成的結果,以及我們是否使用單個實例或多個實例。
  • Angular 2 允許使用與實際提供者關聯的鍵(稱為“令牌”)註冊提供者。此功能對於單元測試很有用,在單元測試中,可以替換一個不會進行服務器調用的模擬類,而無需更改組件代碼。

前文探討瞭如何使用 @Input@Output 註解將數據傳入和傳出組件。本文將介紹 Angular 2 組件的另一個基本方面——它們使用 提供者 的能力。

您可能在組件配置屬性列表中看到過“提供者”,並且您可能意識到它們允許您定義一組可用於組件的可注入對象。這很好,但當然會引出一個問題,“什麼是提供者?”

回答這個問題需要深入探討 Angular 2 的依賴注入 (DI) 系統。我們可能會在以後的博文中專門介紹DI,但Pascal Precht 的一系列文章對此進行了很好的介紹,從這裡開始:https://www.php.cn/link/f7f3bfce09a3008d185e1775549ec2d2 DI 和Angular 2 的DI 系統(如Pascal 的文章中所述),但簡而言之,DI 系統負責:

  • 註冊類、函數或值。在依賴注入的上下文中,這些項目被稱為“提供者”,因為它們會產生結果。例如,類用於提供或產生實例。 (有關提供者類型的更多詳細信息,請參見下文。)
  • 解決提供者之間的依賴關係——例如,如果一個提供者需要另一個提供者。
  • 當我們請求提供者結果時,使提供者的結果可在代碼中使用。此過程(使提供者結果可用於代碼塊)稱為“注入它”。注入提供者結果的代碼邏輯上稱為“注入器”。
  • 維護注入器的層次結構,以便如果組件請求其註入器中不可用的提供者的提供者結果,DI 將向上搜索注入器的層次結構。

在之前的文章中,我們包含了一個圖表,顯示組件形成以根組件開頭的層次結構。讓我們補充該圖表以包含注入器及其註冊的資源(提供者):

Angular 2 Components and Providers: Classes, Factories & Values

圖 1:每個組件都有自己的注入器,用於註冊提供者。注入器創建子注入器,對提供者的請求從本地註入器開始,並向上搜索注入器層次結構。

從上面我們可以看出,雖然組件形成了一個向下定向圖,但它們相關的注入器具有雙向關係:父注入器創建子注入器(向下),當請求提供者時,如果組件自己的注入器中找不到請求的提供者,Angular 2 將向上搜索父注入器(向上)。這意味著較低級別具有相同標識符的提供者將遮蓋(隱藏)較高級別具有相同名稱的提供者。

什麼是提供者?

那麼,注入器在每個級別註冊的這些“提供者”是什麼呢?實際上很簡單:提供者是 Angular 用於提供(產生、生成)我們想要使用的資源或 JavaScript“事物”:

  • 類提供者生成/提供類的實例。
  • 工廠提供者生成/提供運行指定函數時返回的內容。
  • 值提供者不需要像前兩者那樣採取操作來提供結果,它只返回其值。

不幸的是,術語“提供者”有時既指類、函數或值,也指提供者產生的事物——類實例、函數的返回值或返回值。

讓我們看看如何通過使用 MyClass(一個簡單的類,將生成我們想要在應用程序中使用的實例)創建類提供者來向組件添加提供者。

Angular 2 Components and Providers: Classes, Factories & Values

圖 2:具有四個屬性的簡單類。 (代碼屏幕截圖來自 Visual Studio Code)

好了,這就是類。現在讓我們指示 Angular 使用它註冊類提供者,以便我們可以要求依賴注入系統提供一個實例供我們在代碼中使用。我們將創建一個組件 ProvDemo_01.ts,它將用作應用程序的根組件。我們在 bootstrap.ts 中加載此組件並啟動我們的應用程序:

Angular 2 Components and Providers: Classes, Factories & Values

圖 3:啟動應用程序的 bootstrap.ts 文件,它實例化根組件。

如果上面的內容沒有意義,請查看我們之前的文章,該文章介紹了構建簡單的 Angular 2 應用程序的過程。我們的根組件稱為 ProvDemo,存儲庫包含幾個不同版本的該組件。您可以通過更新上面導入 ProvDemo 的行來更改顯示的版本。我們的根組件的第一個版本如下所示:

Angular 2 Components and Providers: Classes, Factories & Values

圖 4:導入 MyClassCompDemo,將其添加到 providers 數組中,並在構造函數參數中將其用作類型。

向此組件添加 MyClass 提供者很簡單:

  • 導入 MyClass
  • 將其添加到 @Componentproviders 屬性
  • 向構造函數添加類型為“MyClass”的參數

在幕後,當 Angular 實例化組件時,DI 系統會為組件創建一個注入器,該注入器註冊 MyClass 提供者。然後,Angular 會看到在構造函數的參數列表中指定的MyClass 類型,並查找新註冊的MyClass 提供者,並使用它來生成一個實例,然後將其分配給“myClass”(初始小寫“m”)。

查找 MyClass 提供者和生成要分配給“myClass”的實例的過程都是 Angular 完成的。它利用 TypeScript 語法來了解要搜索的類型,但 Angular 的注入器負責查找和返回 MyClass 實例。

鑑於上述情況,您可能會得出結論,Angular 會獲取“providers”數組中的類列表,並創建一個簡單的註冊表來檢索該類。但是,為了提高靈活性,存在一個細微的調整。需要“調整”的一個主要原因是幫助我們編寫組件的單元測試,這些組件具有我們不想在測試環境中使用的提供者。對於 MyClass,沒有太多理由不使用真實的東西,但是如果 MyClass 調用服務器來檢索數據,我們可能不想或無法在測試環境中這樣做。為了解決這個問題,我們需要能夠在 ProvDemo 中替換不會進行服務器調用的模擬 MyClass

我們如何進行替換?我們是否需要遍歷所有代碼並將每個 MyClass 引用更改為 MyClassMock?這效率不高,並且是編寫測試的糟糕模式。

我們需要在不更改 ProvDemo 組件代碼的情況下替換提供者實現。為了實現這一點,當 Angular 註冊提供者時,它會設置一個映射,以將鍵(稱為“令牌”)與實際提供者相關聯。在上面的示例中,令牌和提供者是同一事物:MyClass。將 MyClass 添加到 @Component 裝飾器中的 providers 屬性是以下內容的簡寫:

<code>providers: [ provide(MyClass, {useClass: MyClass} ]</code>
登入後複製
登入後複製
登入後複製

這意味著“使用MyClass 作為令牌(鍵)來查找提供者,並將提供者設置為MyClass,以便當我們請求提供者時,依賴注入系統會返回MyClass 實例” 。我們大多數人都習慣於將鍵視為數字或字符串。但在這種情況下,令牌(鍵)是類本身。我們也可以使用字符串作為令牌來註冊提供者,如下所示:

<code>providers: [ provide("aStringNameForMyClass", {useClass: MyClass} ]</code>
登入後複製
登入後複製
登入後複製

那麼,這如何幫助我們進行測試呢?這意味著在測試環境中,我們可以覆蓋提供者註冊,有效地執行以下操作:

<code>provide(MyClass, {useClass: MyClassMock})
</code>
登入後複製

這會將令牌(鍵)MyClass 與類提供者 MyClassMock 關聯起來。當我們的代碼要求 DI 系統在測試中註入 MyClass 時,我們會得到 MyClassMock 的實例,它可以偽造數據調用。最終效果是所有代碼保持不變,我們不必擔心單元測試是否會調用在測試環境中可能不存在的服務器。

注入非類提供者

在上面,我們通過編寫以下代碼將類提供者實例注入到構造函數中:

<code>constructor( myClass: MyClass ) {...}
</code>
登入後複製

TypeScript 允許我們指定 myClass 參數需要是 MyClass 類型,而 DI 系統會完成工作,為我們提供 MyClass 實例。

但是,如果我們使用字符串令牌而不是類,我們如何告訴 Angular 注入我們的提供者結果呢?讓我們編輯 bootstrap.ts 文件以添加新的值提供者並使用字符串令牌註冊它。請記住,值提供者是一種返回與令牌關聯的值的提供者類型。在上面的示例中,我們告訴Angular 通過添加到@Componentproviders 屬性來註冊提供者,但我們也可以通過將它們傳遞到引導函數中來註冊提供者(可以將相同的內容添加到providers 屬性):

Angular 2 Components and Providers: Classes, Factories & Values

圖 5:添加了值提供者的 bootstrap.ts

在這裡,我們通過調用provide 函數並傳入字符串令牌(“SECURITY_KEY”)和一個對象來添加提供者,該對象指定我們想要創建一個值提供者以及提供者本身——在本例中是一個簡單值。現在,我們想將值提供者生成的值注入到我們的構造函數中,但這行不通……

<code>providers: [ provide(MyClass, {useClass: MyClass} ]</code>
登入後複製
登入後複製
登入後複製

這是因為“SECURITY_KEY”不是類型。為了使能夠注入具有非類令牌的提供者成為可能,Angular 為我們提供了 @Inject 參數裝飾器。與所有其他裝飾器一樣,我們需要導入它,然後我們使用它來告訴 Angular 注入與我們的字符串令牌關聯的提供者。為此,我們調整 create ProvDemo_02.ts

Angular 2 Components and Providers: Classes, Factories & Values

圖 6:導入“Inject”裝飾器並使用它來注入使用字符串令牌標識的值提供者。

我們可以使用相同的語法來注入 MyClass 提供者:

<code>providers: [ provide("aStringNameForMyClass", {useClass: MyClass} ]</code>
登入後複製
登入後複製
登入後複製

好了,我們已經了解瞭如何註冊和使用提供者,但讓我們進一步了解提供者返回的內容。

提供者和單例

正如我們在上面看到的,提供者負責生成要注入的事物。類提供者會生成一個實例,然後注入該實例。但是,重要的是要理解,每次注入類提供者結果時,您都不會獲得一個新實例。相反,DI 系統會生成一次實例,將其緩存,並且只要您使用相同的提供者,後續每次注入都會收到相同的實例。

最後一點很重要,因為每個組件都有自己的注入器及其自己的註冊提供者。 MyClass 具有設置為當前時間(以毫秒為單位)的時間屬性和一個隨機數,以幫助我們查看我們每次是否獲得相同的實例。我們將向應用程序添加一個 ChildComp 組件。

Angular 2 Components and Providers: Classes, Factories & Values

圖 7:將 MyClass 注入到構造函數中的 ChildComp

請注意,我們導入 MyClass 並使用它來設置構造函數參數列表中的類型。重要提示:導入的 MyClassChildComp 中的唯一用途是作為 DI 系統用來查找註冊提供者的令牌。 因為 ChildComp 沒有使用該令牌註冊自己的提供者,所以 Angular 會向上查找注入器層次結構以找到一個。為了使這能夠工作,我們需要將 ChildComp 添加到 ProvDemo 組件:

Angular 2 Components and Providers: Classes, Factories & Values

圖 8:向模板中添加了 ChildCompProvDemo

我們導入 ChildComp,向 @Component 添加 directives 屬性以告訴 ProvDemo 我們將使用 ChildComp 組件,並將 ChildComp 元素添加到模板。當應用程序運行時,控制台輸出顯示 ProvDemoChildComp 都收到相同的 MyClass 實例:

<code>providers: [ provide(MyClass, {useClass: MyClass} ]</code>
登入後複製
登入後複製
登入後複製

現在讓我們更改 ChildComp 以向其註入器添加 MyClass 提供者:

Angular 2 Components and Providers: Classes, Factories & Values

圖 9:定義了自己的 MyClass 提供者的 ParentComp

我們唯一更改的是向 @Component 註解添加 providers 屬性。當然,我們可以看到創建了兩個不同的 MyClass 實例:

<code>providers: [ provide("aStringNameForMyClass", {useClass: MyClass} ]</code>
登入後複製
登入後複製
登入後複製

Angular 的此功能為任何一個提供者生成的結果以及我們是否要使用單個實例或多個實例提供了很大的靈活性。例如,您可以將組件放在重複器中,以便多次生成組件。如果此重複組件註冊自己的提供者,則每個組件都會獲得唯一的提供者。但是,如果您只在父組件中註冊提供者,則每個重複實例都會共享父組件的提供者。

總結

在本文中,我們定義了什麼是提供者,並介紹了三種不同類型的提供者。然後,我們研究瞭如何為組件註冊提供者以及如何將提供者生成的結果注入到組件中。我們還研究了 Angular 如何使用注入器層次結構來查找請求的提供者。 Angular 為您提供了更多關於依賴注入系統如何工作以及在何處查找提供者的控制,但以上內容應該可以幫助您開始在 Angular 2 應用程序中創建和使用提供者。

關於 Angular 2 組件、提供者、類、工廠和值的常見問題 (FAQ)

類和工廠在 Angular 2 中有什麼區別?

在 Angular 2 中,類是創建對象的藍圖。它封裝了數據和操作該數據的函數。另一方面,工廠是一種用於創建對象的模式。在 Angular 2 中,工廠用於創建和配置沒有明確類來表示的服務或值。工廠提供了一種根據上下文或配置生成不同類實例的方法。

組件和提供者如何在 Angular 2 中交互?

在 Angular 2 中,組件和提供者協同工作以創建動態且交互式的用戶界面。組件是 Angular 應用程序的構建塊,而提供者用於創建組件可以使用的服務。提供者允許組件共享數據和功能,從而更易於維護和更新應用程序。

值在 Angular 2 中的作用是什麼?

Angular 2 中的值用於向應用程序的其他部分提供配置信息。它們可以注入到控制器、服務和工廠中,允許在運行時配置應用程序的這些部分。這使應用程序更靈活,也更易於測試。

如何在 Angular 2 中綁定類?

Angular 2 中的類綁定是一種動態地向元素添加和刪除 CSS 類的方法。您可以將類綁定到表達式,當該表達式計算結果為 true 時,該類將添加到元素。如果表達式的計算結果為 false,則該類將被刪除。這允許您創建動態且交互式的用戶界面。

在 Angular 2 的上下文中,API 是什麼?

在 Angular 2 的上下文中,API(應用程序編程接口)是一組用於構建和交互軟件應用程序的規則和協議。 Angular 2 提供了一個豐富的 API,允許開發人員使用更少的代碼和精力創建複雜的應用程序。 Angular 2 API 包括用於創建組件、服務、指令、管道等的特性。

如何在 Angular 2 中使用工廠?

要在 Angular 2 中使用工廠,您首先需要定義它。這是通過創建一個返回您希望工廠生成的對象的函數來完成的。然後,您可以使用 .factory 方法將此工廠與 Angular 模塊註冊。註冊工廠後,您可以將其註入到應用程序的其他部分,例如控制器和服務。

如何在 Angular 2 中創建組件?

在 Angular 2 中創建組件涉及定義一個類並使用 @Component 裝飾器對其進行裝飾。 @Component 裝飾器告訴 Angular 該類是一個組件,並提供元數據,這些元數據確定如何在運行時處理、實例化和使用該組件。

如何在 Angular 2 中使用提供者?

Angular 2 中的提供者用於創建和向應用程序部分提供服務。要使用提供者,您首先需要將其與 Angular 模塊註冊。註冊後,可以將提供者註入到組件、其他服務甚至其他提供者中。

如何在 Angular 2 中創建服務?

在 Angular 2 中創建服務涉及定義一個類,該類封裝了服務提供的數和函數。然後,此類將使用 @Injectable 裝飾器進行裝飾,該裝飾器告訴 Angular 該類是一個服務,可以注入到應用程序的其他部分。

如何在 Angular 2 中使用值?

Angular 2 中的值用於向應用程序的其他部分提供配置信息。要使用值,您首先需要將其與 Angular 模塊註冊。註冊後,可以將值注入到控制器、服務和工廠中。

以上是Angular 2組件和提供商:類,工廠和價值觀的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1655
14
CakePHP 教程
1413
52
Laravel 教程
1306
25
PHP教程
1252
29
C# 教程
1226
24
前端熱敏紙小票打印遇到亂碼問題怎麼辦? 前端熱敏紙小票打印遇到亂碼問題怎麼辦? Apr 04, 2025 pm 02:42 PM

前端熱敏紙小票打印的常見問題與解決方案在前端開發中,小票打印是一個常見的需求。然而,很多開發者在實...

神秘的JavaScript:它的作用以及為什麼重要 神秘的JavaScript:它的作用以及為什麼重要 Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

誰得到更多的Python或JavaScript? 誰得到更多的Python或JavaScript? Apr 04, 2025 am 12:09 AM

Python和JavaScript開發者的薪資沒有絕對的高低,具體取決於技能和行業需求。 1.Python在數據科學和機器學習領域可能薪資更高。 2.JavaScript在前端和全棧開發中需求大,薪資也可觀。 3.影響因素包括經驗、地理位置、公司規模和特定技能。

如何實現視差滾動和元素動畫效果,像資生堂官網那樣?
或者:
怎樣才能像資生堂官網一樣,實現頁面滾動伴隨的動畫效果? 如何實現視差滾動和元素動畫效果,像資生堂官網那樣? 或者: 怎樣才能像資生堂官網一樣,實現頁面滾動伴隨的動畫效果? Apr 04, 2025 pm 05:36 PM

實現視差滾動和元素動畫效果的探討本文將探討如何實現類似資生堂官網(https://www.shiseido.co.jp/sb/wonderland/)中�...

JavaScript的演變:當前的趨勢和未來前景 JavaScript的演變:當前的趨勢和未來前景 Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

如何使用JavaScript將具有相同ID的數組元素合併到一個對像中? 如何使用JavaScript將具有相同ID的數組元素合併到一個對像中? Apr 04, 2025 pm 05:09 PM

如何在JavaScript中將具有相同ID的數組元素合併到一個對像中?在處理數據時,我們常常會遇到需要將具有相同ID�...

JavaScript引擎:比較實施 JavaScript引擎:比較實施 Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

前端開發中如何實現類似 VSCode 的面板拖拽調整功能? 前端開發中如何實現類似 VSCode 的面板拖拽調整功能? Apr 04, 2025 pm 02:06 PM

探索前端中類似VSCode的面板拖拽調整功能的實現在前端開發中,如何實現類似於VSCode...

See all articles