美文网首页Angular
从 RouterModule.forRoot 方法说起

从 RouterModule.forRoot 方法说起

作者: 华山令狐冲 | 来源:发表于2022-08-18 23:31 被阅读0次

每个 Angular 开发人员在学习路由设计时,都遇到过如下的代码:

import { RouterModule, Routes } from '@angular/router';

const routes: Routes = [
    { path: '',   redirectTo: '/index', pathMatch: 'full' }
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes)
  ],
  ...
})
export class AppModule { }

这个约定也用在 ngx-bootstrap 和 Angular Material 中。其命名约定意味着,在调用 forRoot() 方法时,必须向应用程序的根 NgModule 注册给定模块。 那为什么它需要在应用程序的根 module 中调用,而不是任何其他 NgModule?

首先,forRoot() 约定返回什么数据类型? 通常,此方法的返回类型是符合 ModuleWithProviders 接口的对象。 这个接口是一个被接受的 NgModule import 并且有两个属性:

interface ModuleWithProviders { 
  ngModule: Type<any>
  providers: Provider[]
}

简而言之,forRoot() 方法返回一个 NgModule 及其提供者依赖项。 这与根 NgModule 有什么关系? 事实上,虽然这个约定暗示着它应用在应用程序的根目录中导入,但在许多情况下,我们可以在非根 NgModule 中导入它,同样会起作用。

下面是一个例子,ngx-bootstrap 中的 ModalModule 使用 forRoot() 约定的方式:

import { NgModule, ModuleWithProviders } from '@angular/core';

import { ModalBackdropComponent } from './modal-backdrop.component';
import { ModalDirective } from './modal.component';
import { PositioningService } from '../positioning';
import { ComponentLoaderFactory } from '../component-loader';

@NgModule({
  declarations: [ModalBackdropComponent, ModalDirective],
  exports: [ModalBackdropComponent, ModalDirective],
  entryComponents: [ModalBackdropComponent]
})
export class ModalModule {
  public static forRoot(): ModuleWithProviders {
    return {ngModule: ModalModule, providers: [ComponentLoaderFactory, PositioningService]};
  }
}

注意: ModalModule 没有在 @NgModule 装饰器中声明任何提供者,而是在静态 forRoot() 方法中声明。

尽管调用 forRoot() 方法理论上可以在子 NgModules 中工作,但在应用程序的根 module 中调用 forRoot,能带来如下收益。当使用 @Injectable 装饰一个类并在 NgModule 中注册为提供者时,这个类被唯一创建一次,并且一个实例在整个应用程序中共享。 当 Angular 引导根 NgModule 时,所有 NgModule 中的所有可用导入,都会在那时注册并可供整个应用程序使用——它们是全局的。 这就是为什么在子 NgModule 中注册的提供程序在整个应用程序中都可用的原因。

相关文章

  • 从 RouterModule.forRoot 方法说起

    每个 Angular 开发人员在学习路由设计时,都遇到过如下的代码: 这个约定也用在 ngx-bootstrap ...

  • 从统筹方法说起

    一直以来觉得国家推行的义务教育除了全民扫盲的基本任务外,还能教会学生自学的能力和培养出终生学习的意识就功德无量了。...

  • RouterModule.forRoot() called tw

    错误消息: RouterModule.forRoot() called twice. Lazy loaded mo...

  • 使用 ts ast 解析并动态添加路由配置项

    方式一 添加路由配置项到 AppModule 中的 RouterModule.forRoot([...]) 里面 ...

  • 从String的equals方法说起

    缘起:调试一段代码判断字符串是否相同时,咋一看去字符串分明是一样的,怎么就是不相等呢?debug一开,瞬间明朗,原...

  • 从“STAR”招聘面试方法说起

    “慧眼识才”一直是HR的本位要求,而在林林种种的求职者中发现优秀、合适的人才是岗位责任也是目的。 一般面试提问...

  • 从我写《说起》说起

    “知青”是当代国人既绕不开,又躲不过的一个沉重话题。不唯是涉及1700万人的上一辈和下一代如此庞大的群体,而是...

  • ConcurrentHashMap源码阅读小结

    putVal 方法总结 说起 ConcurrentHashMap ,当然从入口开始说。该方法要点如下: 1. 不允...

  • spring源码分析四(从refresh方法说起)

    本篇文章开始,我们就进入了spring的源码步骤分析模块,前几篇文章,我已经说明了,我指定了配置文件,然后通过Cl...

  • 从死亡说起

    庄子曾说:生也有涯,而知也无涯。 我们的生命是有限度的,而知识是没有限度的。 随着年龄的增大,我们会开始问自己这样...

网友评论

    本文标题:从 RouterModule.forRoot 方法说起

    本文链接:https://www.haomeiwen.com/subject/rgyygrtx.html