Angular 2使用另一个模块中的组件

时间:2016-09-20 18:55:29

标签: angular typescript angular-module

我有使用angular-cli生成的Angular 2(版本2.0.0 - 最终版)app。

当我创建一个组件并将其添加到AppModule的声明数组时,它一切都很好,它可以工作。

我决定将组件分开,因此我创建了TaskModule和组件TaskCard。现在,我想在TaskCardAppModule组件)的某个组件中使用Board

的AppModule:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { BoardComponent } from './board/board.component';
import { LoginComponent } from './login/login.component';

import { MdButtonModule } from '@angular2-material/button';
import { MdInputModule } from '@angular2-material/input';
import { MdToolbarModule } from '@angular2-material/toolbar';

import { routing, appRoutingProviders} from './app.routing';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

import { UserService  } from './services/user/user.service';
import { TaskModule } from './task/task.module';


@NgModule({
  declarations: [
    AppComponent,
    BoardComponent,// I want to use TaskCard in this component
    LoginComponent,
    PageNotFoundComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    MdButtonModule,
    MdInputModule,
    MdToolbarModule,
    routing,
    TaskModule // TaskCard is in this module
  ],
  providers: [UserService],
  bootstrap: [AppComponent]
})
export class AppModule { }

TaskModule:

import { NgModule } from '@angular/core';
import { TaskCardComponent } from './task-card/task-card.component';

import { MdCardModule } from '@angular2-material/card';

@NgModule({
  declarations: [TaskCardComponent],
  imports: [MdCardModule],
  providers: []
})
export class TaskModule{}

整个项目可在https://github.com/evgdim/angular2(kanban-board文件夹)

上找到

我缺少什么?我需要做些什么才能在TaskCardComponent中使用BoardComponent

8 个答案:

答案 0 :(得分:303)

这里的主要规则是:

在编译组件模板期间适用的选择器由声明该组件的模块以及该模块导入的传输的传递闭包确定。

所以,尝试导出它:

@NgModule({
  declarations: [TaskCardComponent],
  imports: [MdCardModule],
  exports: [TaskCardComponent] <== this line
})
export class TaskModule{}

我应该导出什么?

  

导出其他模块中的组件应该是可声明的类   能够在他们的模板中引用。这些是你的公共课程。   如果您没有导出课程,它将保持私密状态,仅对其他人可见   在此模块中声明的组件。

创建新模块的时间,懒惰与否,任何新模块以及向其声明任何内容,新模块都处于干净状态 (作为Ward Bell)在https://devchat.tv/adv-in-angular/119-aia-avoiding-common-pitfalls-in-angular2

中说

Angular为每个@NgModule创建传递模块

此模块收集从其他模块导入的指令(如果导入模块的传递模块具有导出的指令)或在当前模块中声明

当angular compiles模板属于模块X时,会使用那些在 X.transitiveModule.directives 中收集的指令。

compiledTemplate = new CompiledTemplate(
    false, compMeta.type, compMeta, ngModule, ngModule.transitiveModule.directives);

https://github.com/angular/angular/blob/4.2.x/packages/compiler/src/jit/compiler.ts#L250-L251

enter image description here

这种方式根据上面的图片

  • YComponent无法在其模板中使用ZComponent,因为directives Transitive module Y数组不包含ZComponent,因为YModule尚未在ZModule数组中导入ZComponent,其传递模块包含exportedDirectives

  • XComponent模板中,我们可以使用ZComponent,因为Transitive module X具有包含ZComponent的指令数组,因为 导出模块(XModule)导出指令YModule

  • ZModule导入模块(ZComponent
  • AppComponent模板中,我们无法使用XComponent,因为AppModule导入XModuleXModule不导出XComponent {1}}。

另见

答案 1 :(得分:33)

您必须export

NgModule
@NgModule({
  declarations: [TaskCardComponent],
  exports: [TaskCardComponent],
  imports: [MdCardModule],
  providers: []
})
export class TaskModule{}

答案 2 :(得分:11)

(角度2-角度7)

只能在单个模块中声明组件。 为了使用另一个模块中的组件,您需要执行两个简单的任务:

  1. 导出第一个模块中的组件
  2. 将第一个模块导入第二个模块

第一个模块:

有一个组件(我们称它为“ ImportantCopmonent”),我们想在第二个模块的页面中重复使用。

@NgModule({
declarations: [
    FirstPage,
    ImportantCopmonent // <-- Enable using the component html tag in current module
],
imports: [
  IonicPageModule.forChild(NotImportantPage),
  TranslateModule.forChild(),
],
exports: [
    FirstPage,
    ImportantCopmonent // <--- Enable using the component in other modules
  ]
})
export class FirstPageModule { }

第二个模块:

通过导入FirstPageModule重用“重要提示”

@NgModule({
declarations: [
    SecondPage,
    Example2ndComponent,
    Example3rdComponent
],
imports: [
  IonicPageModule.forChild(SecondPage),
  TranslateModule.forChild(),
  FirstPageModule // <--- this Imports the source module, with its exports
], 
exports: [
    SecondPage,
]
})
export class SecondPageModule { }

答案 3 :(得分:2)

请注意,要创建所谓的“要素模块”,您需要在其中导入CommonModule。因此,您的模块初始化代码将如下所示:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { TaskCardComponent } from './task-card/task-card.component';
import { MdCardModule } from '@angular2-material/card';

@NgModule({
  imports: [
    CommonModule,
    MdCardModule 
  ],
  declarations: [
    TaskCardComponent
  ],
  exports: [
    TaskCardComponent
  ]
})
export class TaskModule { }

此处提供了更多信息:https://angular.io/guide/ngmodule#create-the-feature-module

答案 4 :(得分:0)

无论您想从其他模块使用什么,只需将其放入导出阵列即可。 像这样 -

 @NgModule({
  declarations: [TaskCardComponent],
  exports: [TaskCardComponent],
  imports: [MdCardModule]
})

答案 5 :(得分:0)

解决了如何在其他模块中使用声明在模块中的组件。

基于Royi Namir的解释(非常感谢)。 在使用延迟加载时,缺少在其他模块中重用模块中声明的组件的部分。

第一个:将组件导出到包含该组件的模块中:

@NgModule({
  declarations: [TaskCardComponent],
  imports: [MdCardModule],
  exports: [TaskCardComponent] <== this line
})
export class TaskModule{}

2nd:在要使用TaskCardComponent的模块中:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MdCardModule } from '@angular2-material/card';

@NgModule({
  imports: [
   CommonModule,
   MdCardModule
   ],
  providers: [],
  exports:[ MdCardModule ] <== this line
})
export class TaskModule{}

像这样,第二个模块导入第一个模块,该模块导入和导出组件。

当我们在第二个模块中导入模块时,我们需要再次导出它。现在,我们可以在第二个模块中使用第一个组件。

答案 6 :(得分:0)

一种很棒的方法是从255加载模块,您可以通过调用以下命令在另一个模块中加载模块:

NgModuleFactory

我是从here那里得到的。

答案 7 :(得分:0)

@yurzui,您有正确的解决方案,并感谢您的解释。

我遇到了问题,并且此行:

出口:[组成部分] 解决了。​​