Angular的后院:組件依賴關系的解決

by Dor Moshe

通過Dor Moshe

Angular的后院:解決 組件依賴關系 (Angular’s Backyard: The Resolving of Components Dependencies)

This article originally appeared on dormoshe.io

這篇文章 最初出現在dormoshe.io

Many of us use the Hierarchical Dependency Injection mechanism of Angular. We use it through a service or a component to resolve another service or provider. But, do we know what Angular does in order to resolve the dependencies? Probably not, because Angular takes care of what we need to use it as a black box.

我們中的許多人都使用Angular的分層依賴注入機制。 我們通過服務或組件使用它來解析另一個服務或提供者。 但是,我們知道Angular為了解決依賴關系做什么嗎? 可能不是,因為Angular會照顧我們需要將其用作黑匣子的情況。

In this article, we’ll open the black box and explore the code of the component dependencies resolution mechanism.

在本文中,我們將打開黑盒,并探索組件依賴關系解析機制的代碼。

回到基礎 (Back to the basics)

Dependency Injection (DI) is a powerful pattern for managing code dependencies. Angular’s DI system creates and delivers dependent services “just-in-time”. Angular has its own DI framework, and we can’t build an Angular application without it.

依賴注入 (DI)是一種用于管理代碼依賴關系的強大模式。 Angular的DI系統可以 “及時” 創建并提供相關服務 。 Angular有自己的DI框架,沒有它我們就無法構建Angular應用程序。

The Angular DI system is actually a Hierarchical system. This system supports nested injectors in parallel with the component tree. An injector creates dependencies using providers. We can reconfigure the injectors at any level of that component tree. Behind the scenes, each component sets up its own injector with zero, one, or more providers defined for that component itself.

Angular DI系統實際上是一個層次結構 系統。 該系統支持與組件樹并行的嵌套進樣器。 注入程序使用提供程序創建依賴關系。 我們可以在該組件樹的任何級別重新配置注入器。 在幕后,每個組件都使用為該組件本身定義的零個,一個或多個提供程序來設置自己的注入器

解決順序 (Resolution Order)

The hierarchical DI has an order to the resolution of the dependencies. When a component requests a dependency, if it exists in the @Component.providers array (the component injector), then this dependency will be supplied.

層次化DI對依存關系的解析具有順序。 當組件請求依賴項時,如果它存在于@Component.providers數組(組件注入器)中,則將提供此依賴項。

Elsewhere, Angular continues to the parent component injector and checks again and again. If Angular doesn’t find an ancestor, it will supply this dependency via the application main injector. This is the core concept of the hierarchical DI mechanism.

在其他地方,Angular繼續使用父組件注入器并一次又一次地檢查。 如果Angular找不到祖先,它將通過應用程序主注入器提供此依賴關系。 這是分層DI機制的核心概念。

讓我們看一下代碼 (Let’s see the code)

When Angular instantiates a component, it calls the resolveDep function. This function's signature contains the component view container, the element, the dependency definition and some more arguments. We will focus on the component view and the dependency object. The dependency object contains only one dependency of the component.

Angular實例化組件時,它將調用resolveDep函數。 該函數的簽名包含組件視圖容器,元素,依賴項定義和更多參數。 我們將專注于組件視圖和依賴對象。 依賴性對象僅包含組件的一種依賴性。

Here is the resolveDep function skeleton from the Angular GitHub repository:

這是Angular GitHub存儲庫中的resolveDep函數框架:

The function skeleton contains the main concepts of the resolution, without the edge cases. The full code can be found here. In the next parts, we will explore the function skeleton.

函數框架包含分辨率的主要概念,不包含邊緣情況。 完整的代碼可以在這里找到。 在接下來的部分中,我們將探索功能框架。

保沙 (Pausa)

The Exclamation mark is a new feature of Typescript 2.0. The ! post-fix expression operator may be used to assert that its operand is non-null and non-undefined in contexts where the type checker is unable to conclude that fact. Angular uses this feature frequently, so we should not be afraid.

感嘆號是Typescript 2.0的新功能。 ! 在類型檢查器無法得出結論的上下文中,可以使用后綴表達式運算符來斷言其操作數是非null且未定義的。 Angular經常使用此功能,因此我們不用擔心。

第1部分-準備 (Part 1 — Preparation)

The const startView = view; code saves the original view (the view container of the component) in a variable because the view variable will change soon.

const startView = view; 代碼將原始視圖(組件的視圖容器)保存在一個變量中,因為view變量將很快更改。

The const tokenKey = depDef.tokenKey; code fetches the tokenKey or the dependency key, for example, HeroService_4. This key builds by the dependency name and a generated number to handle the dependency uniquely.

const tokenKey = depDef.tokenKey; 代碼獲取tokenKey或依賴項鍵,例如HeroService_4 。 該鍵由依賴項名稱和生成的數字構建,以唯一地處理依賴項。

The while loop implements the stages of checking the source @Component.providers and the ancestor components. According to the dependency token key, the source component providers will be checked in lines 1–3:

while循環實現檢查源@Component.providers和祖先組件的階段。 根據依賴性令牌密鑰,將在第1–3行中檢查源組件提供者:

If the provider exists on line 4, then the source component satisfies the dependency. So, if the dependency was instantiated in the past on line 6, the instance will return by the resolveDep function at line 10. If this is the first time that the component or its children ask for the dependency it will be created at line 7 and will return by the resolveDep function at line 10.

如果提供程序存在于第4行,則源組件滿足依賴性。 因此,如果依賴關系是在過去的第6行實例化的,則實例將在第10行由resolveDep函數返回。如果這是組件或其子級第一次請求依賴關系,它將在第7行創建,然后將由第10行的resolveDep函數返回。

If the dependency is not found in the view component injector, the elDef = viewParentEl(view) !; and view = view.parent !; will be called to advance the variable to the parent element. The while loop will continue running until the dependency is found in the ancestor injector. If the dependency is still not found after checking all ancestors, the while loop will end and the third part will come into action.

如果在view組件注入器中未找到依賴項,則elDef = viewParentEl(view) !;view = view.parent !; 將被調用以將變量前進到父元素。 while循環將繼續運行,直到在祖先注入器中找到相關性為止。 如果在檢查所有祖先后仍未找到依賴項,則while循環將結束,并且第三部分將開始起作用。

第3部分-根注射器 (Part 3 — Root injector)

If come to this part, the dependency can’t be satisfied by any of the component ancestors injectors. Then the startView or the source component will be checked at line 1:

如果涉及到這一部分,則任何組件祖先注入器都無法滿足這種依賴性。 然后將在第1行檢查startView或源組件:

If the source component or one of its ancestor components was loaded by the Router Outlet (the router component), the root injector is the Outlet Injector. This injector supplies some dependencies like the Router service. Otherwise, the root injector is the bootstrap component’s injector.

如果源組件或其祖先組件之一是由路由器出口(路由器組件)加載的,則注入器為出口注入器 。 該注入器提供了一些依賴性,例如路由器服務。 否則,根注入器是自舉組件的注入器。

If the dependency is found at line 3, then the value will be returned by the resolveDep function. In the other case, part 4 will come into action.

如果在第3行找到依賴項,那么resolveDep函數將返回該值。 在其他情況下,第4部分將生效。

第4部分-應用模塊注入器 (Part 4 — Application module injector)

When we come to this part, it means that the dependency can’t be satisfied by part 2 and part 3. This is the last chance to satisfy the dependency. This part’s code tries to get the dependency from the application module injector or the root module. This module contains the application-wide dependencies:return startView.root.ngModule.injector.get(depDef.token,notFoundValue);

當涉及到這一部分時,這意味著第2部分和第3部分不能滿足依賴關系。這是滿足依賴關系的最后機會。 這部分的代碼試圖從應用程序模塊注入器或根模塊獲取依賴關系。 此模塊包含應用程序范圍的依賴項: return startView.root.ngModule.injector.get(depDef.token,notFoundValue);

This part finishes the resolveDep flow. If the dependency is not found, then Angular can’t satisfy this dependency and it should throw an exception.

本部分完成resolveDep流程。 如果找不到依賴關系,則Angular無法滿足此依賴關系,因此應引發異常。

結論 (Conclusion)

The Hierarchical DI is a core feature that Angular leans on a lot. Sometimes, the resolution process looks complicated and long. It’s very convenient to leave Angular to manage this flow and enjoy the ease of use. Now, after we hiked in the backyard of the component dependency resolution, we know what to expect when we use it.

分層DI是Angular所依賴的一項核心功能。 有時,解析過程看起來很復雜且漫長。 離開Angular管理此流程并享受易用性非常方便。 現在,當我們在組件依賴關系解決方案的后院爬升之后,我們知道使用它時會發生什么。

You can follow me on dormoshe.io or Twitter to read more about Angular, JavaScript and web development.

您可以在dormoshe.io或Twitter上關注我,以了解有關Angular,JavaScript和Web開發的更多信息。

翻譯自: https://www.freecodecamp.org/news/angulars-backyard-the-resolving-of-component-dependencies-2015b40e5bd1/

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

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

相關文章

node中的Stream-Readable和Writeable解讀

在node中,只要涉及到文件IO的場景一般都會涉及到一個類-Stream。Stream是對IO設備的抽象表示,其在JAVA中也有涉及,主要體現在四個類-InputStream、Reader、OutputStream、Writer,其中InputStream和OutputSt…

新Rider預覽版發布,對F#的支持是亮點

JetBrains一直在改進自己的跨平臺.NET IDE產品Rider,努力使其成為Visual Studio家族產品可承擔職能的重要替代者。于今年四月發布的Rider預覽版(EAP 21)提供了一些新特性,其中的亮點在于對函數式編程語言F#的支持。\\鑒于這是Ride…

java代碼整合_java合并多個文件的實例代碼

在實際項目中,在處理較大的文件時,常常將文件拆分為多個子文件進行處理,最后再合并這些子文件。下面就為各位介紹下Java中合并多個文件的方法。Java中合并子文件最容易想到的就是利用BufferedStream進行讀寫。具體的實現方式如下,…

正則表達式的一些規則

1.限定修飾符只對其緊前的元字符有效 String rex8 "\\d\\D"; 上式中,只對\\D有效,即有至少有1個(1個或多個)非數字,\\d仍然只許有一個數字。 2.[1,2,3]和[123]是一樣的轉載于:https://www.cnblogs.com/Sabr…

2016版單詞的減法_在2016年最大的電影中,女性只說了27%的單詞。

2016版單詞的減法by Amber Thomas通過琥珀托馬斯 在2016年最大的電影中,女性只說了27%的單詞。 (Women only said 27% of the words in 2016’s biggest movies.) Movie trailers in 2016 promised viewers so many strong female characters. Jyn Erso…

軟件工程博客---團隊項目---個人設計2(算法)

針對分析我們團隊項目的需求,我們選定Dijkstra算法。 算法的基本思想: Dijkstra算法是由E.W.Dijkstra于1959年提出,又叫迪杰斯特拉算法,它應用了貪心算法模式,是目前公認的最好的求解最短路徑的方法。算法解決的是有向…

UWP 雜記

UWP用選取文件對話框 http://blog.csdn.net/u011033906/article/details/65448394 文件選取器、獲取文件屬性、寫入和讀取、保存讀取和刪除應用數據 https://yq.aliyun.com/articles/839 UWP判斷文件是否存在 http://blog.csdn.net/lindexi_gd/article/details/51387901…

微信上傳素材 java_微信素材上傳(JAVA)

public String uploadMaterial(String url,InputStream sbs,String filelength,String filename, String type) throws Exception {try {DataInputStream innew DataInputStream(sbs);url url.replace("TYPE", type);URL urlObj new URL(url);// 創建Http連接HttpU…

SQL Server讀寫分離之發布訂閱

一、發布 上面有多種發布方式,這里我選擇事物發布,具體區別請自行百度。 點擊下一步、然后繼續選擇需要發布的對象。 如果需要篩選發布的數據點擊添加。 根據自己的計劃選擇發布的時間。 點擊安全設置,設置代理信息。 最后單擊完成系統會自動…

碼農和程序員的幾個重要區別!

如果一個企業老板大聲嚷嚷說,“我要招個程序員”,那么十之八九指的是“碼農”——一種純粹為了錢而寫代碼的技術人員。這其實是一種非常狹隘和錯誤的做法,原因么,且聽我一一道來。1、碼農寫代碼,程序員寫系統從本質上講…

sql server2008禁用遠程連接

1.打開SQL Server 配置管理器,雙擊左邊 SQL Server 網絡配置,點擊TCP/IP協議,在協議一欄中,找到 全部偵聽,修改為否,然后點擊IP地址,將IP地址為127.0.0.1(IPV4)或::1(IPV6)的已啟用修改為是,其它的IP地址的已啟用修改為否 注意:如…

snapchat注冊不到_從Snapchat獲得開發人員職位中學到的經驗教訓

snapchat注冊不到Here are three links worth your time:這是三個值得您花費時間的鏈接: I just got a developer job at Snapchat. Here’s what I learned and how it can help you with your job search (15 minute read) 我剛剛在Snapchat獲得開發人員職位。 這…

java bitmap jar_Java面試中常用的BitMap代碼

引言阿里內推面試的時候被考了一道編程題:10億個范圍為1~2048的整數,將其去重并計算數字數目。我看到這個題目就想起來了《編程珠璣》第一章講的叫做BitMap的數據結構,但是我并沒有在java上實現過,這就比較尷尬了,再加…

移動端工程架構與后端工程架構的思想摩擦之旅(1)

此文已由作者黎星授權網易云社區發布。歡迎訪問網易云社區,了解更多網易技術產品運營經驗記資源投放后端工程的架構調整與優化 架構思考一直以來對軟件工程架構有著極大的興趣,無論是之前負責的移動端Android工程,亦或是現在轉到后端開發后維…

View野指針問題分析報告

【問題描述】 音樂組同事反饋了一個必現Native Crash問題&#xff0c;tombstone如下&#xff1a; pid: 5028, tid: 5028, name: com.miui.player >>> com.miui.player <<< signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 79801f28r0 7ac59c98 r1 …

SicilyFunny Game

一、題目描述 Two players, Singa and Suny, play, starting with two natural numbers. Singa, the first player, subtracts any positive multiple of the lesser of the two numbers from the greater of the two numbers, provided that the resulting number must be non…

java 分布式同步_Java Web分布式集群搭建(三)——Session同步

對于一個業務系統的Tomcat集群來說&#xff0c;必須保證同一個用戶訪問到任一臺服務器上都可以維持之前操作的身份。比如在服務器A進行了登陸&#xff0c;那么在服務器B中也要同步該用戶已登錄的狀態&#xff0c;這里就用到了Session的同步。同步方式sticky模式、復制模式、Ter…

移動應用程序和網頁應用程序_如何不完全破壞您的移動應用程序的用戶界面

移動應用程序和網頁應用程序by Luke Konior盧克科尼爾(Luke Konior) 如何不完全破壞您的移動應用程序的用戶界面 (How to not utterly ruin your mobile app’s user interface) There’s no single universal formula for designing a great user interface (if you discover…

logging記錄日志

日志是一個系統的重要組成部分&#xff0c;用以記錄用戶操作、系統運行狀態和錯誤信息。日志記錄的好壞直接關系到系統出現問題時定位的速度。logging模塊Python2.3版本開始成為Python標準庫的一部分。 日志級別 在最簡單的使用中&#xff0c;我們直接導入logging模塊&#xff…

C#編程之接口

1.定義 接口是把公共方法和屬性組合起來&#xff0c;以封裝特定功能的一個集合。&#xff08;一旦定義了接口&#xff0c;就可以在類中實現它。這樣類就可以支持接口所指定的所有屬性和成員&#xff09; 注意1&#xff1a;接口不能單獨存在。不能像實例化一個類那樣實例化一個接…