參考文章:css
Angular4路由快速入門 http://www.jianshu.com/p/e72c79c6968eangularjs
Angular2文檔學習的知識點摘要——Angular模塊(NgModule)http://lib.csdn.net/article/angularjs/59697?knId=641bootstrap
隨着需求的增長,項目的功能也漸漸複雜起來。這個時候,須要將項目模塊化,將組件、指令和管道打包成內聚的功能塊,正好能夠探索一下Angular4中的子路由以及模塊的懶加載。數組
以前在開發的時候,已經在根模塊實現了簡單的路由功能,能夠總結爲如下三個步驟:promise
一、在app.module.ts文件中加載路由庫,而且在@NgModule中引入RouterModule.forRoot方法,其中,appRoutes是路由數組,它定義了具體的路由規則。app
import { RouterModule } from ‘@angular/router‘; ...... @NgModule({ declarations: [......], imports: [ ......, RouterModule.forRoot(appRoutes), ], providers: [], bootstrap: [AppComponent] })
二、在殼組件中增長導航條,其中routerLink指令指向路由的目標,routerLinkActive爲選中的標籤增長css樣式ide
<a routerLink="/home" routerLinkActive="active"></a>
三、往殼組件的模板中添加一個router-outlet指令,視圖將會被顯示在那裏模塊化
<router-outlet></router-outlet>
如今在這個基礎上想要實現子路由以及模塊的懶加載,文章Angular4路由快速入門中講得比較清楚了,這裏記錄一下在開發過程當中我所遇到的一些問題以及注意點。學習
RouterModule.forRoot() 和 RouterModule.forChild()es5
RouterModule對象爲提供了兩個靜態的方法:forRoot()和forChild()來配置路由信息。
RouterModule.forRoot()方法用於在主模塊中定義主要的路由信息,RouterModule.forChild()與 Router.forRoot()方法相似,但它只能應用在特性模塊中。
即根模塊中使用forRoot(),子模塊中使用forChild()。
子路由
假設在咱們 /settings
設置頁面下有 /settings/profile
和 /settings/password
兩個頁面,分別表示我的資料頁和修改密碼頁。setting做爲一個獨立的功能塊,能夠將其封裝成一個特性模塊。它擁有本身獨立的路由,profile和
password兩個頁面的路由能夠設置成子路由。
import { NgModule } from ‘@angular/core‘; import { CommonModule } from ‘@angular/common‘; import { Routes, RouterModule } from ‘@angular/router‘; export const ROUTES: Routes = [ { path: ‘‘, component: SettingsComponent, children: [ { path: ‘profile‘, component: ProfileSettingsComponent }, { path: ‘password‘, component: PasswordSettingsComponent } ] } ]; @NgModule({ imports: [ CommonModule,//注意這裏引入的CommonModule,它的做用後面會專門講到,這裏不引入的話頁面會報錯 RouterModule.forChild(ROUTES) ], }) export class SettingsModule {}
在SettingsModule 模塊中咱們使用forChild()方法,由於SettingsModule不是咱們應用的主模塊。
另外一個主要的區別是咱們將 SettingsModule 模塊的主路徑設置爲空路徑 (‘‘)。由於若是咱們路徑設置爲 /settings,它將匹配 /settings/settings。經過指定一個空的路徑,它就會匹配 /settings 路徑。
懶加載:loadChildren
在根模塊AppModule中配置setting模塊的路由信息:
export const ROUTES: Routes = [ { path: ‘settings‘, loadChildren: ‘./settings/settings.module#SettingsModule‘ } ]; @NgModule({ imports: [ BrowserModule, RouterModule.forRoot(ROUTES) ], // ... }) export class AppModule {}
這裏使用到了懶加載LoadChildren屬性。這裏沒有將SettingsModule導入到AppModule中,而是經過loadChildren屬性,告訴Angular路由依據loadChildren屬性配置的路徑去加載SettingsModule 模塊。這就是模塊懶加載功能的具體應用,當用戶訪問 /settings/** 路徑的時候,纔會加載對應的 SettingsModule 模塊,這減小了應用啓動時加載資源的大小。
loadChildren的屬性值由三部分組成:
須要導入模塊的相對路徑
#分隔符
導出模塊類的名稱
CommonModule模塊
以前說到在特性模塊中要引入CommonModule模塊,我一開始沒有注意到要在特性模塊中引入,結果在路由的時候頁面報錯:
core.es5.js:1020 ERROR Error: Uncaught (in promise): Error: Template parse errors:
Can‘t bind to ‘ngClass‘ since it isn‘t a known property of ‘div‘.
Can‘t bind to ‘ngForOf‘ since it isn‘t a known property of ‘p‘.
Property binding ngForOf not used by any directive on an embedded template. Make sure that the property name is spelled correctly and all directives are listed in the "@NgModule.declarations".
Can‘t bind to ‘ngIf‘ since it isn‘t a known property of ‘div‘.
......
相似這種一大堆錯誤,感受像是 ‘ngClass‘ ‘ngFor‘ ‘ngIf‘這樣的指令都沒有定義似的。
檢查了很久,發現是由於我在特性模塊中沒有引入CommonModule,引入以後這些錯誤就都消失了。
import { CommonModule } from ‘@angular/common‘;
@NgModule({ imports: [ CommonModule, ...... ], })
那麼CommonModule模塊具體的做用是什麼呢?看這篇文章
CommonModule提供了不少應用程序中經常使用的指令,包括NgIf和NgFor等。更準確地說,NgIf等指令是來自@angular/common的CommonModule中聲明的。
咱們在根模塊AppModule中導入了BrowserModule模塊,BrowserModule導入了CommonModule而且從新導出了它。最終的效果是:只要導入BrowserModule就自動得到了CommonModule中的指令。
導入BrowserModule會讓該模塊公開的全部組件、指令和管道在AppModule下的任何組件模板中直接可用,而不須要額外的繁瑣步驟。可是在其它任何模塊中都不要導入BrowserModule。特性模塊和惰性加載模塊應該改爲導入CommonModule。它們不須要從新初始化全應用級的提供商。 若是你在惰性加載模塊中導入BrowserModule,Angular就會拋出一個錯誤。
以上就是我在這兩天使用Angular子路由和懶加載中遇到的一些問題和總結。
https://blog.csdn.net/xwnxwn/article/details/81908749