NgModule 模組是Angular中一個重要的點,因為Angular的基本建構塊就是NgModule。這篇文章就來帶大家了解Angular中的NgModule模組,希望對大家有幫助!
NgModule 會把相關的程式碼收集到一些功能集中,形成功能單元。在使用Angular CL 指令新建一個專案的時候,會為我們產生一個根模組,命名為 AppModule,根模組有一個根元件AppComponent,引導這個根模組就可以啟動應用程式。
Angular 應用是模組化的,我們在開發中會根據其功能 作用 以及其特性,建立大大小小各種模組,從而構建其成為一個應用程序,任何模組都能包含任意數量的其它組件。 【相關教學推薦:《angularjs影片教學》】
#1.@NgModule()
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
由⬆️程式碼我們可以看到,NgModule 是一個有 @NgModule()
裝飾器的類,它接受一個元資料對象,該物件的屬性用來描述這個模組。
點進去@NgModule()
裝飾器的類別我們可以看到他有以下屬性以及官方的對其屬性的解釋。
export declare interface NgModule { providers?: Provider[];// 本模块向全局服务中贡献的那些服务的创建器。 这些服务能被本应用中的任何部分使用。(你也可以在组件级别指定服务提供商,这通常是首选方式。) declarations?: Array7f1674e11d542355045d5901212c35cb | any[]>;// 那些属于本 NgModule 的组件、指令、管道 imports?: Array7f1674e11d542355045d5901212c35cb | ModuleWithProvidersd0caa276b7a674bb589eb7da91e64d11 | any[]>;// 那些导出了本模块中的组件模板所需的类的其它模块 exports?: Array7f1674e11d542355045d5901212c35cb | any[]>;//那些能在其它模块的组件模板中使用的可声明对象的子集 entryComponents?: Array7f1674e11d542355045d5901212c35cb | any[]>; bootstrap?: Array7f1674e11d542355045d5901212c35cb | any[]>; schemas?: Arraye24d3913b894f1ec3478c7a8ebbd648d; }
以下是本人使用Angular後對此元資料屬性個人口語化的理解
#providers:將本模組所有在元件中注入的服務,在這裡提前定義好,否則在此模組中使用這個服務會有錯誤提示。
declaration:declaration 英文意思為宣告。在這裡聲明一些模組中要使用到的一些元件,指令,管道等。
imports:導入一些模組,比如說我把所有的指令構成一個模組我使用其中某些指令的時候,我可以選擇導入整個指令模組。也可以導入一些透過npm install 安裝的一些模組導入其中,才可以使用。
exports:匯出元件or指令管道等,以供引用此模組的模組可以使用此模組的元件or 指令管道等。
exporyComponents:entry component 表示 angular 的入口元件,可以引導元件是一個入口元件,Angular 會在引導過程中把它載入到 DOM 中。其它入口組件是在其它時機動態載入的。字面上的意義,但是啥時候用呢,比如,我要彈出一個元件,那麼這個元件是要動態載入到DOM中了吧,這個時候就需要將這個元件xxxComponent寫上了。
bootstrap:這個模組啟動的時候應該啟動的元件,上面程式碼可以看到AppModule是作為根模組的啟動元件。
schemas:不屬於Angular的元件或指令的元素或屬性都需要在這裡進行宣告。
2.JavaScript 模組與NgModule
JavaScript 和Angular 都使用模組來組織程式碼,雖然它們的組織形式不同,但Angular 的應用會同時依賴兩者。
JavaScript 模組:
模組是內含 JavaScript 程式碼的獨立檔案。要讓其中的東西可用,要寫一個導出語句
例:
export class AppComponent { ... }
在其他檔案中需要使用
import { AppComponent } from './app.component';
<span class="kwd">而NgModulem模組我們在隨筆的開頭以及介紹他的元數據,對其有一定的了解了。 <br></span>
NgModule 類別與JavaScript 模組有下列關鍵性的不同:
1.NgModule 只綁定了可宣告的類,這些可宣告的類別只是供Angular 編譯器用的。
2.NgModule 與 JavaScript 類別把它所有的成員類別都放在一個巨型檔案中不同,只要把該模組的類別列在它的 @NgModule.declarations 清單中。
3.NgModule 只能匯出可宣告的類別。這可能是它自己擁有的也可能是從其它模組中導入的。它不會聲明或導出任何其它類型的類別。
4.與 JavaScript 模組不同,NgModule 可以透過將服務提供者加到 @NgModule.providers 清單中,來用服務擴展整個應用。
相較之下我們可以看出,NgModulem模組更靈活,擴充性強,更具優勢。
3.常用模組
首先要知道跑起來一個項目需要引用什麼基本的模組,以下是Angular 提供的一些官方的模組。
NgModule |
#匯入自 |
為何使用 |
---|---|---|
|
|
#當你想要在瀏覽器中執行應用程式時 |
|
|
當你想要用 |
|
|
當要建立範本驅動表單時(它包含 |
|
|
#當要建立響應式表單時 |
RouterModule |
@angular/router |
要使用路由功能,並且你要用到 |
4.特性模块的分类
官方文档将模块分为五大类。
虽然我特么当年根本不知道,但是在开发中慢慢摸索其实发现也是根据模块的特性将模块的分类,结果不经相同。
以下为个人在开发中对功能模块的划分
1).业务型模块:整一个应用程序,根据其业务功能我们可以将程序拆分为一个个模块,有很明确的业务特性,围绕其业务功能的模块。例如:用户模块,订单模块等。它有自己独立的路由,有提供与此模块的服务,有一个or多个组件,它惰性懒加载,不会导出or提供任何组件or指令管道,引用官方、本应用程序or第三方的功能模块。它有明确的业务特性,不与别的模块有耦合性。
2).组件模块:应用程序中通常都有规范化的标准设计 ,比如说统一的table,card date 等。将这些都抽出来,做成一个个组件,在模块中导出此组件以供其他模块使用,这样减少了应用程序中重复的样式代码等。曾经我是将所有这种可能多处要使用的封装为组件后,统一在一个模块中导出,后来演变为每一个组件都拆分为一个模块。这样也是发现如果这种通用性的组件多起来的话,假设有二三十个组件在这个UIComponent模块中,而我因为要使用其中一两个组件而导入这个模块,性能是很差的,所以后来都将组件拆分为一个个模块以供业务模块使用,例:DateModule,InputModule..等。
3).服务模块:提供一些通用型的服务。比如说http服务对httpClient二次包装适用于项目,文件服务,配置服务等。
4).其他模块:应用程序中我们会根据需要会做一些指令管道等,其就形成一个指令模块包含应用程序中所有等指令,管道模块包含应用程序中的所有管道。后来觉得,其实这些指令管道不需要集中起来统一导出引用。因为一个模块并不会引用到指令模块中超过百分之八十的指令,so 只需要把它们集中到一个pipe文件夹下,哪个模块需要用到具体个指令or管道,直接声明在其模块中使用便可。
5.创建,导入特性模块
我们将系统根据其功能 业务划分好模块,有利于合作开发,代码的维护和使用。
创建特性模块
ng g m order
ng g c order/list // 订单模块下新建一个list 组件
我们看最后cli给我们生成的目录结构
order.module.ts
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ListComponent } from './list/list.component'; @NgModule({ declarations: [ListComponent],//定义list组件 exports: [ListComponent],//导出list组件 imports: [ CommonModule ] }) export class OrderModule { }
list.component.ts
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-list', templateUrl: './list.component.html', styleUrls: ['./list.component.scss'] }) export class ListComponent implements OnInit { constructor() { } ngOnInit() { } }
导入使用特性模块
现在我们导入根模块
app.module.ts
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; import { OrderModule } from './order/order.module'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, AppRoutingModule, OrderModule //将order模块导入 ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
app.component.html 在跟模块使用
06facb60807abb878507d2bb3961e946 11d44aba3164becbb487ce0e226cda94 4a249f0d628e2318394fd9b75b4636b1 Welcome to {{ title }}! 473f0a7621bec819994bb5020d29372a 16b28748ea4df4d9c2150843fecfba68 3745f326c17c6fdea19a677ddca2b2c758059f9a44a1b811f72224de3dd4205b b06060c1b765d597eda031c226772d27d643f9f2456fe4db0e530134a61924e2
我们可以看到渲染了order模块的list组件
6.惰性加载模块
如果我们将所有的模块都导入根模块,那么应用在初始化加载的时候就会非常慢。这时候我们应该考虑使用惰性加载。根据需求加载相应都模块,减少应用初始化包的大小以及减少加载的时间,提高用户体验性。
惰性加载的模块特点是该模块拥有路由模块。so 接着上面我们创建了一个订单模块 我们给订单模块加上路由。并再创建一个user.module以及user.module模块下的list组件。
order.module
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { OrderRoutingModule } from './order-routing.module'; import { ListComponent } from './list/list.component'; @NgModule({ declarations: [ListComponent], imports: [ CommonModule, OrderRoutingModule ] }) export class OrderModule { }
order-routing.module
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { ListComponent } from './list/list.component'; const routes: Routes = [ { path: 'list', component: ListComponent }, ]; @NgModule({ imports: [RouterModule.forChild(routes)], exports: [RouterModule] }) export class OrderRoutingModule { }
user模块如此类推
接下来配置路由
AppRoutingModule在顶级路由中配置
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; const routes: Routes = [ { path: 'orders', loadChildren: './order/order.module#OrderModule' }, { path: 'orders', loadChildren: './user/user.module#UserModule' } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
我们给app.component.html新增两个button
06facb60807abb878507d2bb3961e946 11d44aba3164becbb487ce0e226cda94 c1a436a314ed609750bd7c7d319db4da Welcome to {{ title }}! 2e9b454fa8428549ca2e64dfac4625cd 16b28748ea4df4d9c2150843fecfba68 7943eda4c5681bf7e23a36d72381a635user65281c5ac262bf6d81768915a4a77ac0 3f02d17bdf61d1ad6ba09c4e21fb2e45order65281c5ac262bf6d81768915a4a77ac0 b06060c1b765d597eda031c226772d27d643f9f2456fe4db0e530134a61924e2
效果图
惰性載入模組有什麼好處呢,在大型專案中往往有許多個模組,而且大很大。如果一個模組1m,如果我們在瀏覽器輸入位址開啟這個應用,瞬間要載入100m 是非常慢的,而且我們並非要是用到著這100個模組。將系統業務拆分為各個模組,劃分好界限。按需加載,我點擊了user 我加載user 模組我出現user 列表,對user進行操作。當我需要使用時才載入極大的減少了頁面初始載入的時間以及減少了資源的消耗。
#7.共享模組
共享模組顧名思義,就是共享於所有的模組中。首先得定義好這個模組的具體功能特性,例如指令、管道和元件等分別封裝成一個個模組,哪些業務模組需要使用到其裡面的功能變導入其模組中便可。簡單的例如,本系統的input 都是統一樣式的,我們可以製作一個input 模組 然後在其他模組直接導入使用。這極大的規範了系統的統一性和降低了以後的維護成本。
更多程式相關知識,請造訪:程式設計影片! !
以上是深入了解Angular中的NgModule(模組)的詳細內容。更多資訊請關注PHP中文網其他相關文章!