<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                本小節讓我們共同完成前后臺的對接。 在前面的章節中在進行班級列表組件對接的時候,我們直接在AppRouting中將klass路徑指定到班級列表組件;并在App模塊中引入了班級列表組件所在的模塊來防止引用錯誤。本節將使用惰性加載的方法將班級列表組件與App模塊進一步分離,從而達到惰性加載的目的(這可以大幅降低打包后項目的啟動時間)。 ## 歷史代碼 在AppRoutingModule中,我們進行了如下聲明: app-routing.module.ts ```js { path: 'klass', component: IndexComponent } @NgModule({ imports: [RouterModule.forRoot(routes)], ① exports: [RouterModule] ② }) export class AppRoutingModule { } ``` * ① 導入RouterModule,并使用routes對該模塊進行路由配置。 * ② 導出配置過的RouterModule,其它模塊若引用該模塊(AppRoutingModule),則將自動引用RouterModule。 ![](https://img.kancloud.cn/f8/d2/f8d2735ad3016998f9b97644ef5a3dc7_935x408.png) 所以當我們在AppModule中有如下代碼時: app.module.ts ``` @NgModule({ declarations: [ AppComponent, TeacherAddComponent, TeacherEditComponent, TeacherIndexComponent ], imports: [ BrowserModule, AppRoutingModule, ① HttpClientModule, FormsModule, KlassModule ② ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } ``` * ① 引入AppRoutingModule,同時引入了由AppRoutingModule配置過的路由模塊RouterModule * ① 由于在路由模塊中定義了`{path: 'klass', component: IndexComponent}`,所以: * ② 聲明引入IndexComponent所在的KlassModule防止依賴錯誤 從思路上來講,上述使用方法沒有任何問題。但隨著在路由中聲明的組件越來越多,App模塊在啟動時將需要加載越來越多的信息來保證在路由中設定的component是可以被正確調用的,這將逐漸影響系統的啟動速度。**惰性加載**便是解決此問題的最佳實踐方法。 ## 惰性加載 app-routing.module.ts ``` { path: 'klass', component: IndexComponent ? loadChildren?: () => import('./klass/klass.module')?.then(mod? => mod.KlassModule?) ? } ]; ``` * ? 當路徑匹配`klass`時,加載子模塊。 * ? 子模塊位于`./klass/klass.module` * ? 子模塊成功加載后,裝入mod對象(./klass/klass.module.ts)。 * ? 返回mod對象中的KlassModule給? 然后測試時有點意思的事情就發生了: ![](https://img.kancloud.cn/72/ca/72cabef301a3649274dbc4ba12ddea89_920x409.gif) 通過觀察我們發現,在啟動首頁的App模塊時,控制臺未報任何錯誤信息,而當我們點擊`班級管理`時,控制臺卻開始報錯了。 這是由于: * 在沒有啟用**惰性加載**前,系統啟動時會嘗試加載所有路由對應的組件 * 而在啟用**惰性加載**后,App模塊在獲取到路由的loadChildren時,得到的是個`function`。當我們嘗試訪問`klass`路徑時,angular才會執行這個`function`會,嘗試得到程序下一步執行的模塊KlassModule,并進入Klass模塊繼續執行。 我們再來觀察一樣修改前后的代碼: app-routing.module.ts ``` { path: 'klass', component: IndexComponent ? loadChildren: () => import('./klass/klass.module').then(mod => mod.KlassModule) ? } ]; ``` 進行類型轉換后: ``` { path: 'klass', component: 類 ---- angular立即嘗試獲取對應該類的對象 loadChildren: 函數 ---- angular立即將該函數載入(但不執行),僅當用戶實際訪問`klass`時才執行該函數。 } ]; ``` 由于`僅當用戶實際訪問`klass`時才執行該函數`,所以即使執行該函數以及在其以后的操作中會發生異常,也僅僅會在訪問`klass`路徑后發生。這也就是為什么當我們點擊`班級管理`后,控制臺才打印部分錯誤的原因。 ## 排錯 讓我們用最原始最有效的方法來解決下這個錯誤: ``` core.js:6014 ERROR Error: Uncaught (in promise): Error: BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead. Error: BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead. ``` 上述提示譯成中文大概是說:`BrowserModule已經加載過了,如果你在惰性加載模塊需要訪問諸如NgIf或NgFor的指令,請使用CommonModule來替換BrowserModule`。 klass/klass.module.ts ``` @NgModule({ declarations: [IndexComponent, AddComponent], imports: [ BrowserModule, ? CommonModule, ? FormsModule, ReactiveFormsModule ] }) ``` #### 測試 此時,再次點擊班級管理錯誤消息,但未顯示任何信息: ![](https://img.kancloud.cn/9c/b2/9cb2e6961a38cd9c309df7df77a12380_542x372.png) 這是由于我們未在班級模塊中定義任何路由的原因。 ## 定義路由 找到klass/klass.module.ts,增加路由配置后代碼如下: ``` import {NgModule} from '@angular/core'; import {IndexComponent} from './index/index.component'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; import {AddComponent} from './add/add.component'; import {CommonModule} from '@angular/common'; import {RouterModule, Routes} from '@angular/router'; /*定義路由*/ const routes: Routes = [ ① { path: '', component: IndexComponent }, { path: 'add', component: AddComponent } ]; /** * 班級模塊 */ @NgModule({ declarations: [IndexComponent, AddComponent], imports: [ CommonModule, FormsModule, ReactiveFormsModule, RouterModule.forChild(routes) ? ] }) export class KlassModule { } ``` * ① 定義路由 * ? 區別為forRoot,使用forChild定義惰性加載模塊路由 在App模塊中,我們使用的forRoot方法,這是由于App模塊是我們系統的根模塊,而forRoot即為:為根模塊定義路由。雖然在惰性加載模塊中使用了forChild來定義子路由,但并不必須這么做。在子模塊中,也是可以使用forRoot來建立根路由的,但通常情況下我們并不這么做。 #### 測試 ![](https://img.kancloud.cn/57/9a/579a4f79e17743dcaed8be4abe91d0aa_468x296.png) # 參考文檔 | 名稱 | 鏈接 | 預計學習時長(分) | | --- | --- | --- | | 源碼地址 | [https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step3.3.6](https://github.com/mengyunzhi/spring-boot-and-angular-guild/releases/tag/step3.3.6) | - | | 惰性加載路由配置 | [https://www.angular.cn/guide/router#lazy-loading-route-configuration](https://www.angular.cn/guide/router#lazy-loading-route-configuration) | 10 |
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看