我用Angular -cli生成了Angular 2.0.0应用。

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

我决定分离组件,所以我创建了一个TaskModule和一个组件TaskCard。现在我想在AppModule的一个组件(Board组件)中使用TaskCard。

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上找到(看板文件夹)

我错过了什么?我要在BoardComponent中使用TaskCardComponent需要做什么?


当前回答

这里的主要规则是:

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

所以,试着导出它:

@NgModule({
  declarations: [TaskCardComponent],
  imports: [MdCardModule],
  exports: [TaskCardComponent] // <== export the component you want to use in another module
})
export class TaskModule{}

我应该导出什么?

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

在你创建一个新模块的那一刻,不管是不是惰性的,任何一个新模块,你在它里面声明了任何东西,这个新模块都有一个干净的状态(正如Ward Bell在https://devchat.tv/adv-in-angular/119-aia-avoiding-common-pitfalls-in-angular2中说的那样)

Angular为每个@ ngmodule创建了可传递的模块。

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

当angular编译属于模块X的模板时,它会使用在X. transitivmodule .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

按照上图这样做

YComponent can't use ZComponent in its template because directives array of Transitive module Y doesn't contain ZComponent because YModule has not imported ZModule whose transitive module contains ZComponent in exportedDirectives array. Within XComponent template we can use ZComponent because Transitive module X has directives array that contains ZComponent because XModule imports module (YModule) that exports module (ZModule) that exports directive ZComponent Within AppComponent template we can't use XComponent because AppModule imports XModule but XModule doesn't exports XComponent.

另请参阅

为什么惰性加载模块必须导入commonModule?角2 Angular模块常见问题 在NgModule中,声明、提供者和导入之间有什么区别?

其他回答

注意,为了创建所谓的“特性模块”,你需要在其中导入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

这里的主要规则是:

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

所以,试着导出它:

@NgModule({
  declarations: [TaskCardComponent],
  imports: [MdCardModule],
  exports: [TaskCardComponent] // <== export the component you want to use in another module
})
export class TaskModule{}

我应该导出什么?

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

在你创建一个新模块的那一刻,不管是不是惰性的,任何一个新模块,你在它里面声明了任何东西,这个新模块都有一个干净的状态(正如Ward Bell在https://devchat.tv/adv-in-angular/119-aia-avoiding-common-pitfalls-in-angular2中说的那样)

Angular为每个@ ngmodule创建了可传递的模块。

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

当angular编译属于模块X的模板时,它会使用在X. transitivmodule .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

按照上图这样做

YComponent can't use ZComponent in its template because directives array of Transitive module Y doesn't contain ZComponent because YModule has not imported ZModule whose transitive module contains ZComponent in exportedDirectives array. Within XComponent template we can use ZComponent because Transitive module X has directives array that contains ZComponent because XModule imports module (YModule) that exports module (ZModule) that exports directive ZComponent Within AppComponent template we can't use XComponent because AppModule imports XModule but XModule doesn't exports XComponent.

另请参阅

为什么惰性加载模块必须导入commonModule?角2 Angular模块常见问题 在NgModule中,声明、提供者和导入之间有什么区别?

你必须从你的NgModule中导出它:

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

无论你想从另一个模块中使用什么,只要把它放在导出数组中。 像这样,

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

一个很好的方法是从NgModuleFactory中加载模块,你可以通过调用下面的方法在另一个模块中加载一个模块:

constructor(private loader: NgModuleFactoryLoader, private injector: Injector) {}

loadModule(path: string) {
    this.loader.load(path).then((moduleFactory: NgModuleFactory<any>) => {
        const entryComponent = (<any>moduleFactory.moduleType).entry;
        const moduleRef = moduleFactory.create(this.injector);
        const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
        this.lazyOutlet.createComponent(compFactory);
    });
}

我从这里得到了这个(存档)。