简体   繁体   English

使用另一个模块的组件

[英]Use component from another module

I have Angular 2.0.0 app generated with angular-cli.我有使用 angular-cli 生成的 Angular 2.0.0 应用程序。

When I create a component and add it to AppModule 's declarations array it's all good, it works.当我创建一个组件并将其添加到AppModule的声明数组时,一切都很好,它可以工作。

I decided to separate the components, so I created a TaskModule and a component TaskCard .我决定将组件分开,所以我创建了一个TaskModule和一个组件TaskCard Now I want to use the TaskCard in one of the components of the AppModule (the Board component).现在我想在TaskCard的组件之一( Board组件)中使用AppModule

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{}

The whole project is available on https://github.com/evgdim/angular2 (kanban-board folder)整个项目可在https://github.com/evgdim/angular2 (看板文件夹)上找到

What am I missing?我错过了什么? What do I have to do to use TaskCardComponent in BoardComponent ?BoardComponent使用TaskCardComponent需要做什么?

The main rule here is that:这里的主要规则是:

The selectors which are applicable during compilation of a component template are determined by the module that declares that component, and the transitive closure of the exports of that module's imports.在组件模板编译期间适用的选择器由声明该组件的模块以及该模块导入的导出的传递闭包确定。

So, try to export it:因此,尝试导出它:

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

What should I export?我应该导出什么?

Export declarable classes that components in other modules should be able to reference in their templates.导出其他模块中的组件应该能够在其模板中引用的可声明类。 These are your public classes.这些是你的公开课。 If you don't export a class, it stays private, visible only to other component declared in this module.如果您不导出类,它会保持私有,仅对在此模块中声明的其他组件可见。

The minute you create a new module, lazy or not, any new module and you declare anything into it, that new module has a clean state (as Ward Bell said in https://devchat.tv/adv-in-angular/119-aia-avoiding-common-pitfalls-in-angular2 )你创建一个新模块的那一刻,无论是否懒惰,任何新模块并在其中声明任何内容,该新模块具有干净的状态(正如 Ward Bell 在https://devchat.tv/adv-in-angular/119 中所说的那样-aia-avoiding-common-pitfalls-in-angular2 )

Angular creates transitive module for each of @NgModule s. Angular 为每个@NgModule s 创建可传递模块

This module collects directives that either imported from another module(if transitive module of imported module has exported directives) or declared in current module .此模块收集从另一个模块导入的指令(如果导入模块的传递模块已导出指令)或在当前模块中声明

When angular compiles template that belongs to module X it is used those directives that had been collected in X.transitiveModule.directives .当 angular 编译属于模块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 https://github.com/angular/angular/blob/4.2.x/packages/compiler/src/jit/compiler.ts#L250-L251

在此处输入图片说明

This way according to the picture above按照上图这样

  • 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. YComponent不能在其模板中使用ZComponent ,因为Transitive module Y directives数组不包含ZComponent因为YModule没有导入ZModule其传递模块在exportedDirectives directives数组中包含ZComponent

  • 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 ZComponentXComponent模板中,我们可以使用ZComponent因为Transitive module X有包含ZComponent指令数组,因为XModule导入模块 ( YModule ) 导出模块 ( ZModule ) 导出指令ZComponent

  • Within AppComponent template we can't use XComponent because AppModule imports XModule but XModule doesn't exports XComponent .AppComponent模板中,我们不能使用XComponent因为AppModule导入XModuleXModule不导出XComponent

See also也可以看看

(Angular 2 - Angular 7) (角 2 - 角 7)

Component can be declared in a single module only.组件只能在单个模块中声明。 In order to use a component from another module, you need to do two simple tasks:为了使用另一个模块的组件,你需要做两个简单的任务:

  1. Export the component in the other module导出其他模块中的组件
  2. Import the other module, into the current module将另一个模块导入到当前模块中

1st Module:第一个模块:

Have a component (lets call it: "ImportantCopmonent"), we want to re-use in the 2nd Module's page.有一个组件(我们称之为:“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 { }

2nd Module:第二模块:

Reuses the "ImportantCopmonent", by importing the FirstPageModule通过导入 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 { }

You have to export it from your NgModule :你必须从你的NgModule export它:

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

Note that in order to create a so called "feature module", you need to import CommonModule inside it.请注意,为了创建所谓的“功能模块”,您需要在其中导入CommonModule So, your module initialization code will look like this:因此,您的模块初始化代码将如下所示:

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 { }

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

Whatever you want to use from another module, just put it in the export array .无论你想从另一个模块使用什么,只要把它放在导出数组中 Like this-像这样-

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

One big and great approach is to load the module from a NgModuleFactory , you can load a module inside another module by calling this:一个伟大而伟大的方法是从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);
    });
}

I got this from here .我从这里得到了这个。

@yurzui you have the right solution and thanks for the explanation. @yurzui你有正确的解决方案,谢谢你的解释。

I had the problem and this line: 我有问题和这一行:

exports: [Commponent] solved it. 出口:[Commponent]解决了它。

SOLVED HOW TO USE A COMPONENT DECLARED IN A MODULE IN OTHER MODULE.解决了如何在其他模块中使用模块中声明的组件。

Based on Royi Namir explanation (Thank you so much).基于 Royi Namir 的解释(非常感谢)。 There is a missing part to reuse a component declared in a Module in any other module while lazy loading is used.在使用延迟加载时,缺少在任何其他模块中重用模块中声明的组件的缺失部分。

1st: Export the component in the module which contains it:第一:导出包含它的模块中的组件:

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

2nd: In the module where you want to use TaskCardComponent:第二:在你想使用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{}

Like this the second module imports the first module which imports and exports the component.像这样,第二个模块导入第一个模块,该模块导入和导出组件。

When we import the module in the second module we need to export it again.当我们在第二个模块中导入模块时,我们需要再次导出它。 Now we can use the first component in the second module.现在我们可以使用第二个模块中的第一个组件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM