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