NG | Module

430 阅读3分钟

1、什么是模块

模块和模块下的组件放到同一个目录下,看起来好点;

根模块导入子模块,可以直接访问子模块的所有组件;

比如:子模块有个login组件,可以直接访问127.0.0.1:4200/login

设置懒加载的话,就相当于多了一级路由;

比如:test模块有个login组件,127.0.0.1:4200/test/login

配置多级路由,在app.module.ts中
providers: [
	{provide:APP_BASE_HREF,useValue:'/xkb/'}
],

2、常用模块

NgModule 导入自 为何使用
BrowserModule @angular/platform-browser 当你想要在浏览器中运行应用时
CommonModule @angular/common 当你想要使用 NgIfNgFor
FormsModule @angular/forms 当要构建模板驱动表单时(它包含 NgModel 双向数据绑定)
ReactiveFormsModule @angular/forms 当要构建响应式表单时
RouterModule @angular/router 要使用路由功能,并且你要用到 RouterLink,.forRoot().forChild()
HttpClientModule @angular/common/http 当你要和服务器对话时

3、特性(自定义)模块

ng g module module_dir/module_name --routing
新创建的模块,要手动导入到app.module中

如果你往该特性模块中加入过任何服务提供商,AppModule 也同样会知道它,其它模块中也一样。不过,NgModule 并不会暴露出它们的组件。

组件是不分模块的,直接在某个模块中导入就行了?

4、providedIn 与 NgModule

//服务
import { Injectable } from '@angular/core';
import { UserModule } from './user.module';

@Injectable({
  providedIn: UserModule,//向指定模块提供服务,'root'表示整个应用都可以使用该服务
})
export class UserService {
}

5、服务提供的限制

懒加载限制提供商(就是服务)作用域

使用组件限定服务提供商的作用域

在模块中提供服务还是在组件中?

通常,要在根模块中提供整个应用都需要的服务,在惰性加载模块中提供限定范围的服务。

6、单例服务

在 Angular 中有两种方式来生成单例服务:

把 @Injectable() 的 providedIn 属性声明为 root。

把该服务包含在 AppModule 或某个只会被 AppModule 导入的模块中。

服务也是不分模块的啊?可以设置提供给谁,那个模块使用这个服务而已?

//6.0以前,服务是注册在 NgModule 的 providers 数组中的;现在还有。
虽然你可能会看到这种形式的代码,但是最好使用在服务自身的 @Injectable() 装饰器上设置 providedIn 属性的形式,因为 Angular 6.0 可以对这些服务进行摇树优化。
@NgModule({
  ...
  providers: [UserService],
  ...
})
//也就是说服务的注入有两种,选一种就好了

7、forRoot模式

如果模块同时定义了 providers(服务)和 declarations(组件、指令、管道),那么,当你同时在多个特性模块中加载此模块时,这些服务就会被注册在多个地方。这会导致出现多个服务实例,并且该服务的行为不再像单例一样。

有多种方式来防止这种现象:

  • 用 providedIn 语法代替在模块中注册服务的方式。
  • 把你的服务分离到它们自己的模块中。
  • 在模块中分别定义 forRoot() 和 forChild() 方法。

8、懒加载特性模块

三步走:

  • 创建该特性模块
  • 创建该特性模块的路由模块
  • 配置相关路由
 forRoot(routes) 表示这是一个根路由模块,在应用中这只会在顶层模块中写一次
 forChild(routes) 添加到各个特性模块中。这种方式下 Angular 就会知道这个路由列表只负责提供额外的路由并且其设计意图是作为特性模块使用,可以在多个模块中使用 forChild()。
app-routing中
const routes: Routes = [
  {
    //懒加载模块,import就是动态导入
    path: 'lazytest',
    loadChildren: () => import('./module_dir/lazy-load/lazy-load.module').then(mod => 	mod.LazyLoadModule)
  }
]

lazytest-routing中(还是和原来一样设置)
const routes: Routes = [
  //这里路径设置为空,在app—routing中设置了整个模块的路由,模块里面的路由就变成子路由了
  { path: '', component: TestlazyComponent },
];