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
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
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í .