核心要點
- 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 將向上搜索注入器的層次結構。
在之前的文章中,我們包含了一個圖表,顯示組件形成以根組件開頭的層次結構。讓我們補充該圖表以包含注入器及其註冊的資源(提供者):
圖 1:每個組件都有自己的注入器,用於註冊提供者。注入器創建子注入器,對提供者的請求從本地註入器開始,並向上搜索注入器層次結構。
從上面我們可以看出,雖然組件形成了一個向下定向圖,但它們相關的注入器具有雙向關係:父注入器創建子注入器(向下),當請求提供者時,如果組件自己的注入器中找不到請求的提供者,Angular 2 將向上搜索父注入器(向上)。這意味著較低級別具有相同標識符的提供者將遮蓋(隱藏)較高級別具有相同名稱的提供者。
什麼是提供者?
那麼,注入器在每個級別註冊的這些“提供者”是什麼呢?實際上很簡單:提供者是 Angular 用於提供(產生、生成)我們想要使用的資源或 JavaScript“事物”:
- 類提供者生成/提供類的實例。
- 工廠提供者生成/提供運行指定函數時返回的內容。
- 值提供者不需要像前兩者那樣採取操作來提供結果,它只返回其值。
不幸的是,術語“提供者”有時既指類、函數或值,也指提供者產生的事物——類實例、函數的返回值或返回值。
讓我們看看如何通過使用 MyClass
(一個簡單的類,將生成我們想要在應用程序中使用的實例)創建類提供者來向組件添加提供者。
圖 2:具有四個屬性的簡單類。 (代碼屏幕截圖來自 Visual Studio Code)
好了,這就是類。現在讓我們指示 Angular 使用它註冊類提供者,以便我們可以要求依賴注入系統提供一個實例供我們在代碼中使用。我們將創建一個組件 ProvDemo_01.ts
,它將用作應用程序的根組件。我們在 bootstrap.ts
中加載此組件並啟動我們的應用程序:
圖 3:啟動應用程序的 bootstrap.ts
文件,它實例化根組件。
如果上面的內容沒有意義,請查看我們之前的文章,該文章介紹了構建簡單的 Angular 2 應用程序的過程。我們的根組件稱為 ProvDemo
,存儲庫包含幾個不同版本的該組件。您可以通過更新上面導入 ProvDemo
的行來更改顯示的版本。我們的根組件的第一個版本如下所示:
圖 4:導入 MyClass
的 CompDemo
,將其添加到 providers
數組中,並在構造函數參數中將其用作類型。
向此組件添加 MyClass
提供者很簡單:
- 導入
MyClass
- 將其添加到
@Component
的providers
屬性 - 向構造函數添加類型為“
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 通過添加到@Component
的providers
屬性來註冊提供者,但我們也可以通過將它們傳遞到引導函數中來註冊提供者(可以將相同的內容添加到providers
屬性):
圖 5:添加了值提供者的 bootstrap.ts
。
在這裡,我們通過調用provide
函數並傳入字符串令牌(“SECURITY_KEY
”)和一個對象來添加提供者,該對象指定我們想要創建一個值提供者以及提供者本身——在本例中是一個簡單值。現在,我們想將值提供者生成的值注入到我們的構造函數中,但這行不通……
<code>providers: [ provide(MyClass, {useClass: MyClass} ]</code>
這是因為“SECURITY_KEY
”不是類型。為了使能夠注入具有非類令牌的提供者成為可能,Angular 為我們提供了 @Inject
參數裝飾器。與所有其他裝飾器一樣,我們需要導入它,然後我們使用它來告訴 Angular 注入與我們的字符串令牌關聯的提供者。為此,我們調整 create ProvDemo_02.ts
:
圖 6:導入“Inject
”裝飾器並使用它來注入使用字符串令牌標識的值提供者。
我們可以使用相同的語法來注入 MyClass
提供者:
<code>providers: [ provide("aStringNameForMyClass", {useClass: MyClass} ]</code>
好了,我們已經了解瞭如何註冊和使用提供者,但讓我們進一步了解提供者返回的內容。
提供者和單例
正如我們在上面看到的,提供者負責生成要注入的事物。類提供者會生成一個實例,然後注入該實例。但是,重要的是要理解,每次注入類提供者結果時,您都不會獲得一個新實例。相反,DI 系統會生成一次實例,將其緩存,並且只要您使用相同的提供者,後續每次注入都會收到相同的實例。
最後一點很重要,因為每個組件都有自己的注入器及其自己的註冊提供者。 MyClass
具有設置為當前時間(以毫秒為單位)的時間屬性和一個隨機數,以幫助我們查看我們每次是否獲得相同的實例。我們將向應用程序添加一個 ChildComp
組件。
圖 7:將 MyClass
注入到構造函數中的 ChildComp
。
請注意,我們導入 MyClass
並使用它來設置構造函數參數列表中的類型。重要提示:導入的 MyClass
在 ChildComp
中的唯一用途是作為 DI 系統用來查找註冊提供者的令牌。 因為 ChildComp
沒有使用該令牌註冊自己的提供者,所以 Angular 會向上查找注入器層次結構以找到一個。為了使這能夠工作,我們需要將 ChildComp
添加到 ProvDemo
組件:
圖 8:向模板中添加了 ChildComp
的 ProvDemo
。
我們導入 ChildComp
,向 @Component
添加 directives
屬性以告訴 ProvDemo
我們將使用 ChildComp
組件,並將 ChildComp
元素添加到模板。當應用程序運行時,控制台輸出顯示 ProvDemo
和 ChildComp
都收到相同的 MyClass
實例:
<code>providers: [ provide(MyClass, {useClass: MyClass} ]</code>
現在讓我們更改 ChildComp
以向其註入器添加 MyClass
提供者:
圖 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中文網其他相關文章!

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

Node.js擅長於高效I/O,這在很大程度上要歸功於流。 流媒體匯總處理數據,避免內存過載 - 大型文件,網絡任務和實時應用程序的理想。將流與打字稿的類型安全結合起來創建POWE

Python和JavaScript在性能和效率方面的差異主要體現在:1)Python作為解釋型語言,運行速度較慢,但開發效率高,適合快速原型開發;2)JavaScript在瀏覽器中受限於單線程,但在Node.js中可利用多線程和異步I/O提升性能,兩者在實際項目中各有優勢。

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Dreamweaver CS6
視覺化網頁開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),