>  기사  >  웹 프론트엔드  >  Angular의 NgModule(모듈)에 대한 심층적인 이해

Angular의 NgModule(모듈)에 대한 심층적인 이해

青灯夜游
青灯夜游앞으로
2022-09-05 19:07:381908검색

NgModule 모듈은 Angular에서 중요한 포인트입니다. 왜냐하면 Angular의 기본 빌딩 블록은 NgModule이기 때문입니다. 이 글은 여러분에게 Angular의 NgModule 모듈을 안내할 것입니다. 여러분에게 도움이 되기를 바랍니다.

Angular의 NgModule(모듈)에 대한 심층적인 이해

NgModule은 관련 코드를 일부 기능 세트로 수집하여 기능 단위를 형성합니다. Angular CL 명령을 사용하여 새 프로젝트를 생성하면 AppModule이라는 루트 모듈이 생성됩니다. 루트 모듈에는 루트 구성 요소 AppComponent가 있으며 이 루트 모듈을 안내하여 애플리케이션을 시작할 수 있습니다. Angular 애플리케이션은 개발 중에 기능과 특성에 따라 다양한 크고 작은 모듈을 구성하여 애플리케이션으로 구축할 것입니다. [관련 튜토리얼 권장 사항: "angularjs 비디오 튜토리얼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>"]

    1.@NgModule()
  • ng g m order
  • ⬆️코드에서 NgModule은 메타데이터 개체를 허용하는 @NgModule() 데코레이터가 있는 클래스임을 알 수 있습니다. 이 모듈을 설명하는 데 사용됩니다.
  • @NgModule() 데코레이터 클래스를 클릭하면 다음과 같은 속성과 해당 속성에 대한 공식적인 설명이 있음을 확인할 수 있습니다.

    ng g c order/list  // 订单模块下新建一个list 组件
  • 다음은 Angular
  • providers

    를 사용한 후 이 메타데이터 속성에 대한 개인적인 구어체 이해입니다. 이 모듈의 구성 요소에 삽입된 모든 서비스를 여기에서 미리 정의하세요. 그렇지 않으면 이 모듈에서 사용됩니다. 이 서비스에 대한 오류 메시지가 됩니다.

declaration

: 선언은 영어로 선언을 의미합니다. 여기에서 일부 모듈에서 사용할 일부 구성 요소, 지침, 파이프 등을 선언합니다.

imports

: 일부 모듈을 가져옵니다. 예를 들어 모든 지침을 하나의 모듈로 결합한 경우 일부 지침을 사용할 때 전체 지침 모듈을 가져오도록 선택할 수 있습니다. npm install을 통해 설치된 일부 모듈을 사용하기 전에 가져올 수도 있습니다.

: 진입 구성요소는 각도의 진입 구성요소를 나타냅니다. 부팅 가능한 구성요소는 진입 구성요소이며 Angular는 부팅 프로세스 중에 이를 DOM에 로드합니다. 다른 항목 구성 요소는 다른 경우에 동적으로 로드됩니다. 문자 그대로의 의미입니다. 예를 들어 컴포넌트를 팝업하려면 이 컴포넌트를 DOM에 동적으로 로드해야 합니다. 이때 컴포넌트 xxxComponent를 작성해야 합니다. 앱을 브라우저에서 실행하고 싶을 때
exports

: 이 모듈의 구성 요소 또는 명령 파이프라인 등을 사용하기 위해 이 모듈을 참조하는 모듈에 대한 구성 요소 또는 명령 파이프라인 등을 내보냅니다.

exporyComponents

🎜🎜bootstrap🎜: 이 모듈이 시작될 때 시작되어야 하는 구성 요소입니다. 위 코드에서 AppModule이 루트 모듈의 시작 구성 요소임을 알 수 있습니다. 🎜🎜🎜🎜🎜schemas🎜: Angular 구성 요소나 지시어에 속하지 않는 요소나 속성은 여기에서 선언해야 합니다. 🎜🎜🎜🎜🎜🎜2. JavaScript 모듈과 NgModule🎜🎜🎜🎜모두 모듈을 사용하여 코드를 구성하지만 Angular 애플리케이션은 둘 다에 의존합니다. 🎜🎜🎜JavaScript 모듈🎜: 🎜🎜모듈은 JavaScript 코드를 포함하는 독립적인 파일입니다. 콘텐츠를 사용할 수 있게 하려면 내보내기 명세서를 작성해야 합니다🎜🎜예: 🎜
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 { }
🎜다른 파일에서는 🎜
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() {
  }

}
🎜를 사용해야 합니다. 에세이의 시작 부분과 그를 소개하는 메타데이터를 통해 우리는 이에 대해 어느 정도 이해할 수 있습니다.
🎜🎜🎜NgModule 클래스에는 JavaScript 모듈과 다음과 같은 주요 차이점이 있습니다. 🎜🎜🎜🎜1 NgModule은 선언 가능한 클래스만 바인딩하며 이러한 선언 가능한 클래스는 Angular 컴파일러에서만 사용됩니다. 🎜🎜🎜🎜2.NgModule 모든 멤버 클래스를 거대한 파일에 저장하는 JavaScript 클래스와 달리 @NgModule.declarations 목록에 모듈의 클래스를 나열하기만 하면 됩니다. 🎜🎜🎜🎜3.NgModule은 선언 가능한 클래스만 내보낼 수 있습니다. 이는 자체 모듈일 수도 있고 다른 모듈에서 가져올 수도 있습니다. 다른 유형의 클래스를 선언하거나 내보내지 않습니다. 🎜🎜🎜🎜4. JavaScript 모듈과 달리 NgModule은 @NgModule.providers 목록에 서비스 공급자를 추가하여 서비스로 전체 애플리케이션을 확장할 수 있습니다. 🎜🎜🎜🎜 이에 비해 NgModulem 모듈은 더 유연하고 확장 가능하며 더 많은 장점을 가지고 있음을 알 수 있습니다. 🎜🎜🎜🎜3. 일반적으로 사용되는 모듈 🎜🎜🎜🎜먼저 프로젝트를 실행하기 위해 어떤 기본 모듈을 참조해야 하는지 알아야 합니다. 다음은 Angular에서 제공하는 공식 모듈입니다. 🎜🎜🎜🎜🎜🎜NgModule🎜🎜🎜🎜가져옴🎜🎜🎜🎜왜 사용하나요🎜

BrowserModuleBrowserModule

@angular/platform-browser

当你想要在浏览器中运行应用时

CommonModule

@angular/common

当你想要使用 NgIf 和 NgFor 时

FormsModule

@angular/forms

当要构建模板驱动表单时(它包含 NgModel )

ReactiveFormsModule

@angular/forms

当要构建响应式表单时

RouterModule @angular/router

要使用路由功能,并且你要用到 RouterLink,.forRoot() 和 .forChild() 时

HttpClientModule

@angular/common/http

@angular/platform-browser

🎜🎜🎜 🎜 CommonModule🎜🎜🎜🎜@angular/common🎜🎜🎜🎜 NgIfNgFor를 사용하려는 경우 템플릿 기반 양식을 구축하려는 경우(NgModel 코드> 포함)🎜🎜🎜🎜🎜🎜ReactiveFormsModule🎜🎜🎜🎜@angular/forms🎜🎜🎜🎜반응형 폼을 구축하고 싶을 때🎜🎜🎜🎜🎜RouterModule🎜🎜@angular/router🎜🎜🎜라우팅 기능을 사용하려면 서버와 통신하려면 RouterLink,.forRoot().forChild()를 사용해야 합니다🎜🎜🎜🎜🎜

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개의 모듈을 사용할 필요는 없습니다. 시스템 사업을 다양한 모듈로 분할하여 경계를 명확히 합니다. 요청 시 로드하고, 사용자를 클릭하고, 사용자 모듈을 로드하고, 사용자 목록이 나타나고, 사용자를 대상으로 작업했습니다. 꼭 사용해야 할 때만 로딩하면 페이지 초기 로딩 시간이 크게 줄어들고 리소스 소모도 줄어듭니다.

7. 공유 모듈

이름에서 알 수 있듯이 공유 모듈은 모든 모듈 간에 공유됩니다. 먼저, 모듈로 패키징되는 지침, 파이프라인, 구성요소 등 이 모듈의 특정 기능적 특성을 정의해야 합니다. 어떤 비즈니스 모듈이 내부 기능을 사용해야 하는지를 해당 모듈로 가져올 수 있습니다. 간단한 예로, 이 시스템의 입력은 모두 동일한 스타일입니다. 입력 모듈을 만든 다음 이를 다른 모듈로 직접 가져올 수 있습니다. 이는 시스템의 통일성을 크게 표준화하고 향후 유지 관리 비용을 절감합니다.

더 많은 프로그래밍 관련 지식을 보려면 프로그래밍 비디오를 방문하세요! !

위 내용은 Angular의 NgModule(모듈)에 대한 심층적인 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제