Angular 2 Usa el componente de otro módulo

Tengo la aplicación Angular 2 (versión 2.0.0 – final) generada con angular-cli.

Cuando creo un componente y lo AppModule la matriz de declaraciones de AppModule todo está bien, funciona.

Decidí separar los componentes, así que creé un TaskModule y un componente TaskCard . Ahora quiero usar la TaskCard en uno de los componentes del AppModule (el componente de la 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{} 

Todo el proyecto está disponible en https://github.com/evgdim/angular2 (carpeta kanban-board)

¿Qué me estoy perdiendo? ¿Qué tengo que hacer para usar TaskCardComponent en BoardComponent ?

La regla principal aquí es que:

Los selectores que son aplicables durante la comstackción de una plantilla de componente están determinados por el módulo que declara ese componente, y el cierre transitivo de las exportaciones de las importaciones de ese módulo.

Por lo tanto, intente exportarlo:

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

¿Qué debo exportar?

Exportar clases declarables que los componentes de otros módulos deberían poder referenciar en sus plantillas. Estas son tus clases públicas. Si no exporta una clase, se mantiene privada, visible solo para otros componentes declarados en este módulo.

En el momento en que crea un módulo nuevo, flojo o no, cualquier módulo nuevo y declara algo en él, ese nuevo módulo tiene un estado limpio (como dijo Ward Bell en https://devchat.tv/adv-in-angular/119 -aia-evitando-comunes-trampas-en-angular2 )

Angular crea un módulo transitivo para cada uno de los @NgModule s.

Este módulo recostack directivas que, o bien se importan de otro módulo (si el módulo transitivo del módulo importado tiene directivas exportadas) o se declaran en el módulo actual .

Cuando la plantilla de comstackción angular pertenece al módulo X , se utilizan aquellas directivas que se han recostackdo en 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

De esta manera de acuerdo con la imagen de arriba

  • YComponent no puede usar ZComponent en su plantilla porque las directives array del Transitive module Y no contienen ZComponent porque YModule no ha importado ZModule cuyo módulo transitivo contiene ZComponent en la matriz ZComponent .

  • Dentro de la plantilla XComponent podemos usar ZComponent porque el Transitive module X tiene una matriz de directivas que contiene ZComponent porque XModule importa el módulo ( YModule ) que exporta el módulo ( ZModule ) que exporta la directiva ZComponent

  • Dentro de la plantilla de AppComponent no podemos usar XComponent porque AppModule importa XModule pero XModule no exporta XComponent .

Ver también

  • ¿Por qué el módulo de carga lenta tiene que importar CommonModule? Angular 2

  • Preguntas frecuentes sobre módulos angulares

  • Cuál es la diferencia entre declaraciones, proveedores e importación en NgModule

Tienes que export desde tu NgModule :

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

Tenga en cuenta que para crear un llamado “módulo de características”, necesita importar CommonModule dentro de él. Entonces, el código de inicialización de tu módulo se verá así:

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

Más información disponible aquí: https://angular.io/guide/ngmodule#create-the-feature-module

Lo que sea que desee utilizar de otro módulo, simplemente colóquelo en la matriz de exportación . Me gusta esto-

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

RESUELVE CÓMO UTILIZAR UN COMPONENTE DECLARADO EN UN MÓDULO EN OTRO MÓDULO.

Basado en la explicación de Royi Namir (Muchas gracias). Falta una parte para reutilizar un componente declarado en un Módulo en cualquier otro módulo mientras se usa la carga diferida.

Primero: Exporte el componente en el módulo que lo contiene:

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

2º: en el módulo en el que desea utilizar 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{} 

De esta manera, el segundo módulo importa el primer módulo que importa y exporta el componente.

Cuando importamos el módulo en el segundo módulo, necesitamos exportarlo de nuevo. Ahora podemos usar el primer componente en el segundo módulo.

Un gran enfoque es cargar el módulo desde una NgModuleFactory , puede cargar un módulo dentro de otro módulo llamando a esto:

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

Obtuve esto de aquí .