摘要:生成項目后,中的代碼這里調用了包中導出的函數這個函數是瀏覽器平臺的工廠函數執行會返回瀏覽器平臺的實例函數是通過函數創建的這個函數接收個參數父平臺工廠函數平臺名稱服務提供商的數組顧名思義函數的作用是創建平臺工廠的函數在框架被加
cli生成項目后,main.ts中的代碼
import { enableProdMode } from "@angular/core"; import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; import { AppModule } from "./app/app.module"; import { environment } from "./environments/environment"; if (environment.production) { enableProdMode(); } platformBrowserDynamic().bootstrapModule(AppModule).catch(err => console.error(err));
這里調用了@angular/platform-browser-dynamic包中導出的platformBrowserDynamic函數,這個函數是瀏覽器平臺的工廠函數,執行會返回瀏覽器平臺的實例
export const platformBrowserDynamic = createPlatformFactory(platformCoreDynamic, "browserDynamic", INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS);
platformBrowserDynamic函數是通過createPlatformFactory函數創建的,這個函數接收3個參數,parentPlatformFactory(父平臺工廠函數),name(平臺名稱),providers(服務提供商的數組)
export function createPlatformFactory( parentPlatformFactory: ((extraProviders?: StaticProvider[]) => PlatformRef) | null, name: string, providers: StaticProvider[] = []): (extraProviders?: StaticProvider[]) => PlatformRef { const desc = `Platform: ${name}`; const marker = new InjectionToken(desc); return (extraProviders: StaticProvider[] = []) => { let platform = getPlatform(); if (!platform || platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) { if (parentPlatformFactory) { parentPlatformFactory( providers.concat(extraProviders).concat({provide: marker, useValue: true})); } else { const injectedProviders: StaticProvider[] = providers.concat(extraProviders).concat({provide: marker, useValue: true}); createPlatform(Injector.create({providers: injectedProviders, name: desc})); } } return assertPlatform(marker); }; }
在angular框架被加載后,會執行這個函數,并傳入了三個參數分別為 platformCoreDynamic, "browserDynamic", INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS
看第一個參數platformCoreDynamic:
export const platformCoreDynamic = createPlatformFactory(platformCore, "coreDynamic", [ {provide: COMPILER_OPTIONS, useValue: {}, multi: true}, {provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS]}, ]);
第一個參數也是通過createPlatformFactory函數創建的一個工廠函數,這里執行的時候又傳入了三個參數platformCore,"coreDynamic"和一個提供商數組
第一個參數platformCore:
export const platformCore = createPlatformFactory(null, "core", _CORE_PLATFORM_PROVIDERS);
又是通過createPlatformFactory函數創建的... ,但好在沒有在繼續傳入父平臺作為參數,所以應用初始化時執行的第一個函數就是這個了
這里有點繞,屢一下函數的執行過程:
createPlatformFactory(null, "core", _CORE_PLATFORM_PROVIDERS)執行返回platformCore函數
createPlatformFactory(platformCore, "coreDynamic", [...])執行返回platformCoreDynamic函數
createPlatformFactory(platformCoreDynamic, "browserDynamic", INTERNAL_BROWSER_DYNAMIC_PLATFORM_PROVIDERS)執行返回platformBrowserDynamic函數
platformBrowserDynamic()執行返回平臺實例
要注意到這里創建的都是工廠函數,而不是平臺實例,在angular框架被加載后,就會開始執行,此時應用還沒有正式啟動
在執行platformBrowserDynamic()后,應用開始啟動,實例化core平臺(這里的調用順序就不貼出來了,雖然工廠函數的調用順序是platformBrowserDynamic->platformCoreDynamic->platformCore,但是實例化的只有core平臺)
coreDynamic平臺和browserDynamic平臺的工廠函數并不是創建子平臺的實例,而是添加服務提供商,被實例化的只有一個平臺實例,只不過會改變PLATFORM_IDtoken的值
core平臺實例化之前,首先創建了應用的根注入器
createPlatform(Injector.create({providers: injectedProviders, name: desc}));
在core平臺實例化過程中,又通過子平臺工廠函數的參數和區域變量,傳入了一些服務提供商,然后將這些提供商統一注冊到了注入器中:
// 這里的變量名是我命名的不是源碼中的名字,用以區分各個平臺下注冊的提供商 export const browserDynamic_PROVIDERS: StaticProvider[] = [ {provide: PLATFORM_ID, useValue: PLATFORM_BROWSER_ID}, {provide: PLATFORM_INITIALIZER, useValue: initDomAdapter, multi: true}, {provide: PlatformLocation, useClass: BrowserPlatformLocation, deps: [DOCUMENT]}, {provide: DOCUMENT, useFactory: _document, deps: []}, { provide: COMPILER_OPTIONS, useValue: {providers: [{provide: ResourceLoader, useClass: ResourceLoaderImpl, deps: []}]}, multi: true }, {provide: PLATFORM_ID, useValue: PLATFORM_BROWSER_ID} ]; export const coreDynamic_PROVIDERS: StaticProvider[] = [ {provide: COMPILER_OPTIONS, useValue: {}, multi: true}, {provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS]} ]; export const core_PROVIDERS: StaticProvider[] = [ // Set a default platform name for platforms that don"t set it explicitly. {provide: PLATFORM_ID, useValue: "unknown"}, {provide: PlatformRef, deps: [Injector]}, {provide: TestabilityRegistry, deps: []}, {provide: Console, deps: []}, ]
然后進行初始化的操作,包括BrowserDomAdapter(DOM適配器)和BrowserGetTestability
export function createPlatform(injector: Injector): PlatformRef { if (_platform && !_platform.destroyed && !_platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) { throw new Error( "There can be only one platform. Destroy the previous one to create a new one."); } _platform = injector.get(PlatformRef); // 初始化操作 browserDynamic平臺下的PLATFORM_INITIALIZER服務 const inits = injector.get(PLATFORM_INITIALIZER, null); if (inits) inits.forEach((init: any) => init()); return _platform; }
這里初始化操作是通過PLATFORM_INITIALIZERtoken注入,然后遍歷執行,所以也可以在應用中注入PLATFORM_INITIALIZER,然后執行一些啟動時的自定義的任務.
到這里,core平臺的實例化就完成了.
ps:
除了platform-browser-dynamic之外還有platform-browser模塊,這兩個模塊的區別是編譯方式的不同,platform-browser-dynamic模塊提供jit編譯,也就是說編譯在瀏覽器內完成,而platform-browser模塊提供aot編譯,編譯在本地完成.
在代碼層面上來說,platform-browser模塊下core平臺的子平臺只有browser平臺,而platform-browser-dynamic模塊下,core平臺的子平臺包含coreDynamic平臺和browserDynamic平臺,并添加了額外的服務提供商
{ provide: COMPILER_OPTIONS, useValue: {providers: [{provide: ResourceLoader, useClass: ResourceLoaderImpl, deps: []}]}, multi: true }, {provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS]},
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99924.html
摘要:生成項目后,中的代碼這里調用了包中導出的函數這個函數是瀏覽器平臺的工廠函數執行會返回瀏覽器平臺的實例函數是通過函數創建的這個函數接收個參數父平臺工廠函數平臺名稱服務提供商的數組顧名思義函數的作用是創建平臺工廠的函數在框架被加 cli生成項目后,main.ts中的代碼 import { enableProdMode } from @angular/core; import { platf...
摘要:而且大部分人一聽說就會本能地避開。至于啟動項目,都是這一行開始的。應用是模塊化的,它擁有自己的模塊化系統,稱作。開場來個自我介紹 angular 源碼閱讀 項目地址 文章地址 angular 版本:8.0.0-rc.4 歡迎看看我的類angular框架 關于為什么寫這么一個項目 聲明:僅僅為個人閱讀源碼的理解,不一定完全正確,還需要大佬的指點。 其實市面上很多關于 vue和react 的源碼...
摘要:我們使用了模式書寫,并引入了思想,這些以前只在里見到的設計,現在里也有體現,并且在本章中會著重講解多的協作。如果之前寫過,那對于這種書寫方式一定無比熟悉。每次數據的變更,無論是還是,都將變化冒泡到,然后由再向下逐級推送各組件是否重繪。 前集回顧 在上一章里我們講了如何在angular2下開發一個component(還沒做的趕緊去學吧)。我們使用了Unidirectional Data ...
angular2是什么?我猜不容我贅述,各位一定略有耳聞,無論是曾經AngularJS的擁躉,亦或是React的粉絲,都或多或少的對她有過一點了解。未見其物、先聞其聲,angular2在問世之前已經做足了宣傳,想必諸位也一定被下面各種詞匯所震懾,什么:TypeScript、 ES5、 ES6、 Dart、 Immutable、 Unidirectional Data Flow、 Reactive ...
摘要:通過增加刪除元素改變布局的。譬如和控制元素顯示隱藏,或者改變元素行為的。譬如設計看過我之前介紹以手寫依賴注入的朋友應該已經對行為驅動多少有些了解了。她有,并且包含了至少一個和一個標簽。,將左邊的事件傳遞給了右邊的表達式通常就是事件處理函數。 前集回顧 在上一章里我們講了如何為angular2搭建開發環境(還沒搭起來的趕緊去看哦),并使之跑起來我們的第一個My First Angular...
閱讀 1936·2021-11-15 17:58
閱讀 2131·2021-10-19 11:45
閱讀 3482·2021-09-02 15:40
閱讀 2595·2021-07-25 10:50
閱讀 3745·2019-08-30 15:56
閱讀 3146·2019-08-30 12:44
閱讀 1028·2019-08-26 13:38
閱讀 1869·2019-08-23 18:29