首页 文章

angular2 - 'imports'和'exports'如何在Angular2模块中工作?

提问于
浏览
23

我是Angular2的新手,很难理解 @NgModule imports and exports in Angular2. 的情况

以下面的代码为例:

@NgModule({
  imports: [
    RouterModule.forChild(heroesRoutes)
  ],
  exports: [
    RouterModule
  ]
})

在导入部分 what am I importing ? 路由器模块,或forChild()函数,或函数forChild()返回的模块?哪一个 ?

另外,当我再次导出 RouterModule 时,documentation表示以下内容:

我们的最后一步是重新导出RouterModule . 通过重新导出RouterModule,我们的功能模块将在使用我们的路由模块时提供路由器指令 .

So does that mean that whatever module imports the above NgModule, will have access to all the code in the RouterModule ?

有点像我在C中编写包含math.h的自定义头文件,如果我现在使用该头文件,我不再需要在我的程序中单独包含math.h . 我的比喻是否正确?

有人可以在这里解释核心概念,这样每次看到新代码时我都不会感到难过 .

4 回答

  • 3

    Angular2中的模块与Angular1模块非常相似,Angular1模块基本上是一个包含所有可以一起发货的零碎的包 .

    例如,如果您有一个LoginComponent,由于某些原因连接到一个服务,即LoginService,它执行一些http请求以获取一些用户信息,您可以创建一个LoginModule,它将LoginComponent和LoginService作为LoginModule一起发送 .

    LoginService也可以使用一些接口,例如UserInterface,再次,将LoginModule传递给消费者是有意义的 .

    因此,如果我是您的客户并且我将使用您的常规登录功能,那么我将更容易导入您的LoginModule以及我的AppComponent可用的所有好东西!

    所以,你的LoginModule类(它只是一个简单的javascript文件和一个函数)应该导出我要使用的LoginModule :) .

    LoginModule看起来像这样:

    @NgModule({
          declaration:[LoginComponent , LogoutComponent], 
          exports: [
            LoginComponent , LogoutComponent
          ],
          providers:[LoginService]
        })
        export class LoginModule{
    
        }
    

    所以在我的AppModule中,我会导入你的LoginModule .

    @NgModule({
      imports: [
        LoginModule,
        RouterModule.forChild(heroesRoutes) // another imported module that I need beside the Login
      ]
    })
    

    但是:

    如果我知道你的代码并且我不想要任何额外的函数和组件以及类和东西而且我只需要使用你的LoginComponent,我可能更愿意只声明我正在使用LoginComponent而我不想导入你的大量LoginModule!

    @NgModule({
      declaration:[LoginComponent],
      imports: [
        RouterModule.forChild(heroesRoutes)
      ]
    })
    

    只有当LoginComponent没有对LoginService有任何直接依赖时,这只会起作用,其他明智的Angular会抱怨并说:

    **No Provider for LoginService**
    

    在这种情况下,如果你是一个坚强的人并且你仍然不相信使用LoginModule,你可以帮助Angular并提供如下的LoginService:

    @NgModule({
      declaration:[LoginComponent],// declaring it 
      providers:[LoginService],// providing it
      imports: [
        RouterModule.forChild(heroesRoutes)
      ]
    });
    

    因此,这可能会继续,您可能会发现导入整个LoginModule更容易,并让模块本身完成所有工作 .

    这就是LoginModule .


    现在,回答你关于 forChild 的问题 .

    LoginModule可能希望在为您提供并不总是需要的类时做一些额外的事情,在这种情况下,您可能已经改进了LoginModule并为其添加了一些糖 .

    @NgModule({
       declaration:[LoginComponent , LogoutComponent], 
       exports: [LoginComponent , LogoutComponent],
       providers:[LoginService]
    })  
    export class LoginModule{
      public static logAndLoadModule(message){
         console.log('I first log and then give you my module');
         return {
          ngModule: LoginModule
         }
      }
      public static alertAndLoadModule(message){
          alert('I first alert and then give you my module');
         return {
          ngModule: LoginModule
         }
      }
    }
    

    在这种情况下,看起来模块可以在开始给我它的包时记录一些东西 . 所以我可能会这样使用它:

    @NgModule({
          imports: [
            LoginModule.logAndLoadModule(),
            RouterModule.forChild(heroesRoutes)
          ]
        })
    

    是不是 logAndLoadModule 这类似于RouterModule的 forChild 功能?

    是的,它仍然给你LoginModule但它也做了一些额外的事情 .

    所以你仍然可以导入LoginModule,但你也可以使用它的警报和日志 .

    更新:

    export class LoginModule ,表示当前文件(可能是login.module.ts或其他)正在导出一个名为LoginModule的类,它可以从其他文件导入,它与Angular无关,这只是将编译为javascript的typescript .

    在哪里

    @NgModule({
          exports: [
            LoginModulesBrother
          ]
        })
      export class LoginModule{
    
      }
    

    上面是Angular2特定语言,意味着LoginModule也是导出LoginModulesBrother,所以谁曾经导入LoginModule,也可以访问LoginModulesBrother .

    因此,LoginModulesBrother是另一个可能在其他地方定义的模块,如:

    @NgModule({
          // some other magic here 
      })
      export class LoginModulesBrother{
    
      }
    

    所以一般来说,导入和导出 class ,这可能是什么(一个模块,一个组件,一个管道,一个简单的函数或任何东西)只是打字稿,但导出数组和导入数组只是Angular特定的语言,对打字稿没有任何意义 .

  • 34

    如果使用 <router-outlet> 组件或 routerLinkrouterLinkActive 指令,则需要将 RouterModule 添加到要使用的每个模块的 imports: [] 任何这些 .

    对于任何指令,组件或管道,这都是相同的 . Angular仅在模块中实例化它们,如果它们通过导入已知 .

    如果将模块添加到 imports: [] 所有指令,则导出中列出的组件和管道可供导入模块使用 .

    模块还可以重新导出其他模块,这使得导入模块可以使用这些模块的所有导出指令,组件和管道 .

    也可以看看

  • 0

    可以找到router.forChild(ROUTES)(和一般的路由器)的很好的解释和示例on youtube .

    这是Angular Router的主要贡献者之一Victor Savkin的演讲 .

    在阅读了关于路由器的许多教程和SO答案之后,他的演讲帮助我将它全部包装起来,看看它如何在一个实例上运行 .

    Note: 该链接在6:22启动视频,Victor解释延迟加载 . 您可以从视频的开头开始,了解有关路由器工作原理的更多详细信息 .

  • 1

    来自RouterModule文档:

    • forRoot 创建一个包含所有指令,给定路由和路由器服务本身的模块 .

    • forChild 创建一个包含所有指令和给定路由的模块,但是 does not include the router service .

    您可以使用 forRoot 为根模块配置路由,为功能模块配置 forChild .

    您不需要功能模块中的 router service ,因为您只需要一个适用于您的应用程序的应用程序,您应按惯例在 AppRoutingModule 中配置(假设您的根模块名为 AppModule ) .

    以您的代码段为例:

    @NgModule({
          imports: [
            RouterModule.forChild(heroesRoutes)
          ],
          exports: [
            RouterModule
          ]
        })
       export class AppRoutingModule {}
    

    RouterModule 有一些声明,如 routerLinkrouterLinkActive ,可能由 AppModule 中的组件使用 .

    要使这些声明在 AppModule 中可用,您可以将 RouterModule 直接导入 AppModule ,也可以通过 AppRoutingModule 导出它 .

相关问题