W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
Angular 是當(dāng)前以及未來(lái)的 Angular 名稱。
AngularJS 特指 Angular 的所有 1.x 版本。
本指南介紹了一些用來(lái)將 AngularJS 項(xiàng)目高效地逐塊遷移到 Angular 平臺(tái)上的工具。 本章和從 AngularJS 升級(jí)很像,但是這里會(huì)用輔助函數(shù) ?downgradeModule()
? 取代 ?UpgradeModule
?。這會(huì)影響到應(yīng)用如何啟動(dòng),以及變更檢測(cè)事件如何在兩個(gè)框架之間傳播。 它能讓你逐步升級(jí),并提高混合式應(yīng)用的運(yùn)行速度,并讓你能在升級(jí)過(guò)程中盡早用上 Angular 中的最新特性。
在討論你應(yīng)該如何用 ?downgradeModule()
? 來(lái)創(chuàng)建混合式應(yīng)用之前,你可以先采取一些措施來(lái)簡(jiǎn)化升級(jí)過(guò)程,甚至在開(kāi)始升級(jí)之前就可以做。 無(wú)論你用哪種方式升級(jí),這些步驟都是一樣的,請(qǐng)參考從 AngularJS 升級(jí)的準(zhǔn)備工作部分。
使用 Angular 中的 ?ngUpgrade
?庫(kù),你可以通過(guò)構(gòu)建混合式應(yīng)用來(lái)逐步升級(jí)現(xiàn)有的 AngularJS 應(yīng)用。在這些混合式應(yīng)用中,你可以混用 AngularJS 和 Angular 的組件與服務(wù),并讓它們天衣無(wú)縫地進(jìn)行互操作。 這意味著你不用一次性完成遷移工作,因?yàn)樵谶^(guò)渡階段兩個(gè)框架可以自然共存。
無(wú)論選擇 ?downgradeModule()
? 還是 ?UpgradeModule
?,升級(jí)的基本原則都是一樣的:無(wú)論是混合式應(yīng)用背后的心智模型,還是 ?upgrade/static
? 的用法。 要了解更多,參閱從 AngularJS 升級(jí)的 ngUpgrade 工作原理部分。
從 AngularJS 升級(jí)中的變更檢測(cè)部分僅僅適用于使用 ?
UpgradeModule
?的應(yīng)用。 雖然你處理變更檢測(cè)的方式和 ?downgradeModule()
?(本章的重點(diǎn))不同,不過(guò)讀一下變更檢測(cè)部分還是能為后續(xù)內(nèi)容提供一些有用的上下文知識(shí)。
如前所述,?downgradeModule()
? 和 ?UpgradeModule
?之間的一個(gè)關(guān)鍵區(qū)別,就是如何進(jìn)行變更檢測(cè),以及檢測(cè)結(jié)果如何在兩個(gè)框架之間傳播。
使用 ?UpgradeModule
?,兩套變更檢測(cè)系統(tǒng)綁得更緊密一些。 一旦應(yīng)用中的 AngularJS 部分發(fā)生了某些變化,變更檢測(cè)就會(huì)自動(dòng)在 Angular 部分觸發(fā)它,反之亦然。 這很方便,因?yàn)樗WC了任何一個(gè)框架都不會(huì)丟失重要的變更。不過(guò),其實(shí)大多數(shù)情況下并不需要運(yùn)行這些額外的變更檢測(cè)。
而 ?downgradeModule()
? 會(huì)避免顯式觸發(fā)變更檢測(cè),除非它確信應(yīng)用的其它部分對(duì)此感興趣。 比如,如果被降級(jí)的組件定義了 ?@Input()
?,當(dāng)那個(gè)值發(fā)生變化時(shí),應(yīng)用就可能需要知道。 因此,?downgradeComponent()
? 就會(huì)自動(dòng)在該組件上觸發(fā)變更檢測(cè)。
但是,大多數(shù)情況下,應(yīng)用的其它地方并不會(huì)關(guān)心某個(gè)組件中進(jìn)行的局部更改。 比如,如果用戶點(diǎn)擊了某個(gè)表單的提交按鈕,通常會(huì)由組件自行處理這個(gè)操作的結(jié)果。 話雖如此,但在某些情況下,你可能希望把這些變化傳播到應(yīng)用中由另一個(gè)框架控制的部分。 這時(shí)候,你就有責(zé)任通過(guò)手動(dòng)觸發(fā)變更檢測(cè)來(lái)通知相關(guān)方。
如果你希望某些代碼片段在應(yīng)用的 AngularJS 部分觸發(fā)變更檢測(cè),就要把它包在 scope.$apply() 中。 同樣,要想在 Angular 中觸發(fā)變更檢測(cè),就要調(diào)用 ?ngZone.run()
?。
很多情況下,是否運(yùn)行額外的變更檢測(cè)可能并不重要。不過(guò),在較大或變更檢測(cè)較多的應(yīng)用中,它們可能會(huì)產(chǎn)生顯著地影響。 通過(guò)讓你更精細(xì)的控制變更檢測(cè)的傳播方式,?downgradeModule()
? 可以讓你的混合式應(yīng)用達(dá)到更好地性能。
AngularJS 和 Angular 都有自己的模塊概念,來(lái)幫你把應(yīng)用按功能組織成內(nèi)聚的代碼塊。
它們?cè)诩軜?gòu)和實(shí)現(xiàn)方面的細(xì)節(jié)有很大不同。在 AngularJS 中,你可以用 angular.module() 指定名字和依賴,以創(chuàng)建一個(gè)模塊。 然后,你可以使用它的各種方法添加資產(chǎn)。在 Angular 中,你要?jiǎng)?chuàng)建一個(gè)帶有 ?NgModule
?裝飾器的類,靠這個(gè)裝飾器的元數(shù)據(jù)來(lái)描述這些資產(chǎn)。
在混合式應(yīng)用中,你同時(shí)運(yùn)行著兩個(gè)框架。這意味著你至少需要一個(gè)來(lái)自 AngularJS 的模塊和一個(gè)來(lái)自 Angular 的模塊。
大多數(shù)情況下,你可以使用與常規(guī)應(yīng)用程序相同的方式來(lái)指定模塊。然后,使用 ?upgrade/static
? 輔助函數(shù)來(lái)讓兩個(gè)框架了解對(duì)方使用的資產(chǎn)。這叫做"升級(jí)(upgrading)"和"降級(jí)(downgrading)"。
定義:
- 升級(jí):讓 AngularJS 中的資產(chǎn),比如組件或服務(wù),可用于應(yīng)用中的 Angular 部分。
- 降級(jí):讓 Angular 中的資產(chǎn),比如組件或服務(wù),可用于應(yīng)用中的 AngularJS 部分
依賴互聯(lián)中最重要的部分之一是把兩個(gè)主模塊聯(lián)結(jié)在一起。這就是 ?downgradeModule()
? 的用武之地。使用它來(lái)創(chuàng)建 AngularJS 模塊(你可以在 AngularJS 主模塊中把這個(gè)模塊用作依賴項(xiàng)),該模塊將引導(dǎo)你的 Angular 主模塊,并啟動(dòng)混合式應(yīng)用中的 Angular 部分。從某種意義上說(shuō),它把 NgModule "降級(jí)"成了 AngularJS 模塊。
有幾點(diǎn)需要注意:
downgradeModule()
?。?downgradeModule()
? 所需要的只是一個(gè)用來(lái)創(chuàng)建模塊實(shí)例 "配方"(比如工廠函數(shù))。
下面是如何使用 ?downgradeModule()
? 來(lái)聯(lián)結(jié)兩個(gè)模塊的例子。
// Import `downgradeModule()`.
import { downgradeModule } from '@angular/upgrade/static';
// Use it to downgrade the Angular module to an AngularJS module.
const downgradedModule = downgradeModule(MainAngularModuleFactory);
// Use the downgraded module as a dependency to the main AngularJS module.
angular.module('mainAngularJsModule', [
downgradedModule
]);
如前所述,?downgradeModule()
? 需要知道如何實(shí)例化 Angular 模塊。你可以通過(guò)提供可以創(chuàng)建 Angular 模塊實(shí)例的工廠函數(shù)來(lái)定義該配方。 ?downgradeModule()
? 接受兩種類型的工廠函數(shù):
NgModuleFactory
?(extraProviders: StaticProvider[]) => Promise<NgModuleRef>
?當(dāng)傳入 ?NgModuleFactory
?時(shí),?downgradeModule()
? 會(huì)把它傳給 ?platformBrowser
?的 ?bootstrapModuleFactory()
? 來(lái)實(shí)例化模塊。它與預(yù)先(AOT)編譯模式兼容。 預(yù)先編譯能讓你的應(yīng)用加載更快。
另外,你還可以傳入一個(gè)普通函數(shù),它要返回一個(gè)解析為 ?NgModuleRef
?(比如你的 Angular 模塊) 的 Promise。該函數(shù)接收一個(gè)額外 ?Providers
?的數(shù)組,這個(gè)數(shù)組可以在所返回 ?NgModuleRef
?的 ?Injector
?中可用。 例如,如果你在使用 ?platformBrowser
?或 ?platformBrowserDynamic
?,就可以把 ?extraProviders
?數(shù)組傳給它們:
const bootstrapFn = (extraProviders: StaticProvider[]) => {
const platformRef = platformBrowserDynamic(extraProviders);
return platformRef.bootstrapModule(MainAngularModule);
};
// or
const bootstrapFn = (extraProviders: StaticProvider[]) => {
const platformRef = platformBrowser(extraProviders);
return platformRef.bootstrapModuleFactory(MainAngularModuleFactory);
};
使用 ?NgModuleFactory
?需要更少的樣板代碼,并且是一個(gè)很好的默認(rèn)選項(xiàng),因?yàn)樗С?nbsp;AOT 開(kāi)箱即用。 使用自定義函數(shù)需要稍多的代碼,但是給你提供了更大的靈活性。
?downgradeModule()
? 和 ?UpgradeModule
?之間的另一個(gè)關(guān)鍵區(qū)別,就是后者要求你預(yù)先實(shí)例化 AngularJS 和 Angular 的模塊。 這意味著你必須為實(shí)例化應(yīng)用中的 Angular 而付出代價(jià) —— 即使你以后不會(huì)用到任何 Angular 資產(chǎn)。 ?downgradeModule()
? 則不那么激進(jìn)。它只會(huì)在第一次用到時(shí)才實(shí)例化 Angular 部分,也就是說(shuō),當(dāng)它需要實(shí)例化一個(gè)降級(jí)后的組件時(shí)。
你還可以更進(jìn)一步,甚至不必將應(yīng)用程序中 Angular 部分的代碼下載到用戶的瀏覽器中 —— 直到需要它的那一刻。 當(dāng)不需要初始渲染或用戶尚未訪問(wèn)到混合式應(yīng)用中的 Angular 部分時(shí),這特別有用。
舉一些例子:
你可能已經(jīng)猜到了,你不需要修改引導(dǎo)現(xiàn)有 AngularJS 應(yīng)用的方式。?UpgradeModule
?需要一些額外的步驟,但 ?downgradeModule()
? 能自行引導(dǎo) Angular 模塊,你只要為它提供配方即可。
要開(kāi)始使用任何 ?upgrade/static
? API,你仍然要像在普通 Angular 應(yīng)用中一樣加載 Angular 框架。要想用 SystemJS 做到這一點(diǎn),你可以遵循升級(jí)的準(zhǔn)備工作中的指導(dǎo),有選擇的從快速上手項(xiàng)目的 Github 倉(cāng)庫(kù)中復(fù)制代碼。
你還需要用 ?npm install @angular/upgrade --save
? 安裝 ?@angular/upgrade
? 包,并添加一個(gè)指向 ?@angular/upgrade/static
? 包的映射:
'@angular/upgrade/static': 'npm:@angular/upgrade/fesm2015/static.mjs',
接下來(lái),創(chuàng)建一個(gè) ?app.module.ts
? 文件,并添加如下 ?NgModule
?類:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
imports: [
BrowserModule
]
})
export class MainAngularModule {
// Empty placeholder method to satisfy the `Compiler`.
ngDoBootstrap() {}
}
這個(gè)最小的 ?NgModule
?導(dǎo)入了 ?BrowserModule
?,Angular 每個(gè)基于瀏覽器的應(yīng)用都會(huì)導(dǎo)入該模塊。 它還定義了一個(gè)空的 ?ngDoBootstrap()
? 方法,來(lái)防止 ?Compiler
?返回錯(cuò)誤。 在這里它是必要的,因?yàn)?nbsp;?NgModule
?裝飾器上還沒(méi)有聲明 ?bootstrap
?。
你不用把 ?
bootstrap
?聲明加到 ?NgModule
?裝飾器上,因?yàn)?nbsp;AngularJS 擁有應(yīng)用的根組件,并且 ?ngUpgrade
?會(huì)負(fù)責(zé)啟動(dòng)必要的組件。
現(xiàn)在你可以用 ?downgradeModule()
? 把 AngularJS 和 Angular 的模塊聯(lián)結(jié)在一起。
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { downgradeModule } from '@angular/upgrade/static';
const bootstrapFn = (extraProviders: StaticProvider[]) => {
const platformRef = platformBrowserDynamic(extraProviders);
return platformRef.bootstrapModule(MainAngularModule);
};
const downgradedModule = downgradeModule(bootstrapFn);
angular.module('mainAngularJsModule', [
downgradedModule
]);
現(xiàn)有的 AngularJS 代碼仍然在和以前一樣正常工作,但你已經(jīng)可以開(kāi)始添加新的 Angular 代碼了。
?downgradeModule()
? 和 ?UpgradeModule
?之間的區(qū)別就是這些。 其余的 ?upgrade/static
? API 和概念的工作方式在不同的混合式應(yīng)用中都完全一樣了。
雖然可以降級(jí)可注入對(duì)象,但在實(shí)例化 Angular 模塊之前,無(wú)法使用降級(jí)后的可注入對(duì)象。 安全起見(jiàn),你需要確保降級(jí)后的可注入對(duì)象不會(huì)用于應(yīng)用中不受 Angular 控制的任何地方。
比如,在只使用 Angular 組件的已升級(jí)組件中可以使用降級(jí)后的服務(wù),但是,不能在那些不依賴 Angular 的 AngularJS 組件中使用它,也不能從其它模塊中使用降級(jí)過(guò)的 Angular 組件。
你可以像在任何其它 Angular 應(yīng)用中一樣,利用混合式應(yīng)用的預(yù)先(AOT)編譯功能。 混合式應(yīng)用的設(shè)置與預(yù)先(AOT)編譯一章所講的大致相同,但 ?index.html
? 和 ?main-aot.ts
? 略有差異。
AOT 需要在 AngularJS 的 ?index.html
? 中的 ?<script>
? 標(biāo)簽中加載所有 AngularJS 文件。
你還要將所生成的 ?MainAngularModuleFactory
?傳給 ?downgradeModule()
? 函數(shù),而不是自定義引導(dǎo)函數(shù)。
import { downgradeModule } from '@angular/upgrade/static';
import { MainAngularModuleNgFactory } from '../aot/app/app.module.ngfactory';
const downgradedModule = downgradeModule(MainAngularModuleNgFactory);
angular.module('mainAngularJsModule', [
downgradedModule
]);
這就是當(dāng)你想讓混合式應(yīng)用受益于 AOT 時(shí)所要做的一切。
該頁(yè)面介紹了如何借助 ?upgrade/static
? 包,來(lái)按照你自己的節(jié)奏逐步升級(jí)現(xiàn)有的 AngularJS 應(yīng)用。并且升級(jí)過(guò)程中不會(huì)方案此應(yīng)用的進(jìn)一步開(kāi)發(fā)。
具體來(lái)說(shuō),本章介紹了如何使用 ?downgradeModule()
? 來(lái)代替 ?UpgradeModule
?,為混合式應(yīng)用提供更好的性能和更大的靈活性。
總結(jié),?downgradeModule()
? 中的關(guān)鍵差異性因素是:
當(dāng)你希望混合式應(yīng)用的 AngularJS 部分和 Angular 部分保持松耦合時(shí),使用 ?downgradeModule()
? 是個(gè)很好的選擇。 你仍然可以混用并匹配兩個(gè)框架中的組件和服務(wù)。作為回報(bào),?downgradeModule()
? 為你提供了更大的控制權(quán)和更好的性能。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: