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

Evg*_*rov 171 typescript angular-module angular

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

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

我决定将组件分开,所以我创建了TaskModule一个组件TaskCard.现在我想用TaskCard在的组成部分之一AppModule(的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 { }
Run Code Online (Sandbox Code Playgroud)

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{}
Run Code Online (Sandbox Code Playgroud)

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

我错过了什么?我必须做的,用TaskCardComponentBoardComponent

yur*_*zui 332

这里的主要规则是:

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

所以,尝试导出它:

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

我应该出口什么?

导出其他模块中的组件应该能够在其模板中引用的可声明类.这些是你的公共课程.如果不导出类,则它保持私有,仅对此模块中声明的其他组件可见.

你创建一个新模块,懒惰与否,任何新模块并向其声明任何内容的那一刻,新模块都处于干净状态(正如Ward Bell在 https://devchat.tv/adv-in-angular/119中所述) -aia-avoid-common-pitfalls-in-angular2)

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

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

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

compiledTemplate = new CompiledTemplate(
    false, compMeta.type, compMeta, ngModule, ngModule.transitiveModule.directives);
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

这种方式根据上图

  • YComponent不能ZComponent在其模板中使用因为directives数组Transitive module Y不包含ZComponent因为YModule没有导入ZModule其传递模块包含ZComponentexportedDirectives数组中.

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

  • AppComponent模板中,我们不能使用XComponent因为AppModule导入XModuleXModule不导出XComponent.

也可以看看

  • 真是个好消息.你创建了这幅画吗?如果是这样,我会说不出话来.不是每个人都在努力回答他们.谢谢 (14认同)
  • 如何在导入模块的路径定义中使用此"TaskCardComponent"? (11认同)
  • @Royi是的,这是我的照片:)它基于https://github.com/angular/angular/blob/master/packages/compiler/src/metadata_resolver.ts#L424的源代码 (3认同)

mxi*_*xii 36

你必须export从你的NgModule:

@NgModule({
  declarations: [TaskCardComponent],
  exports: [TaskCardComponent],
  imports: [MdCardModule],
  providers: []
})
export class TaskModule{}
Run Code Online (Sandbox Code Playgroud)

  • 这有效,直到在 AppModule 中导入 TaskModule。当 TaskModule 延迟加载时它会失败。 (2认同)
  • 如何知道TaskModule是否是Lazyloaded?以及如何解决它? (2认同)

小智 22

(角度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 { }
Run Code Online (Sandbox Code Playgroud)

第二模块:

通过导入FirstPageModule,重用“ ImportantCopmonent”

@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 { }
Run Code Online (Sandbox Code Playgroud)

  • 虽然不像原来那样冗长,但这是您需要做的两件事,而导出组件是最常被忘记的一件事。这是一个简单的答案。 (6认同)