Angular 2 Use componente de outro módulo

Eu tenho Angular 2 (versão 2.0.0 – final) app gerado com angular-cli.

Quando eu crio um componente e o adiciono ao array de declarações do AppModule , tudo funciona bem.

Decidi separar os componentes, então criei um TaskModule e um componente TaskCard . Agora quero usar o TaskCard em um dos componentes do AppModule (o componente 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 o projeto está disponível em https://github.com/evgdim/angular2 (pasta kanban-board)

O que eu estou sentindo falta? O que devo fazer para usar o TaskCardComponent no TaskCardComponent ?

A regra principal aqui é que:

Os seletores aplicáveis ​​durante a compilation de um modelo de componente são determinados pelo módulo que declara esse componente e o fechamento transitivo das exportações das importações desse módulo.

Então, tente exportar:

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

O que devo exportar?

Exporte as classs declaráveis ​​que os componentes em outros módulos devem poder referenciar em seus modelos. Estas são suas aulas públicas. Se você não exportar uma class, ela permanecerá privada, visível apenas para outro componente declarado neste módulo.

No minuto em que você cria um novo módulo, preguiçoso ou não, qualquer novo módulo e você declara algo nele, esse novo módulo tem um estado limpo (como Ward Bell disse em https://devchat.tv/adv-in-angular/119 -aia-evitando-armadilhas comuns-em-angular2 )

Angular cria um módulo transitivo para cada um dos @NgModule s.

Este módulo coleta diretivas que são importadas de outro módulo (se o módulo transitivo do módulo importado tiver diretivas exportadas) ou declaradas no módulo atual .

Quando o modelo de compilation angular que pertence ao módulo X , é usado as diretivas que foram coletadas em 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

insira a descrição da imagem aqui

Desta forma, de acordo com a imagem acima

  • YComponent não pode usar o ZComponent em seu modelo porque a matriz de directives do Transitive module Y não contém ZComponent porque o YModule não importou o ZModule cujo módulo transitivo contém ZComponent na matriz ZComponent .

  • Dentro do template XComponent , podemos usar ZComponent porque Transitive module X possui uma matriz de diretivas que contém ZComponent porque o XModule importa o módulo ( YModule ) que exporta o módulo ( ZModule ) que exporta a diretiva ZComponent

  • No modelo AppComponent , não podemos usar o XComponent porque o AppModule importa o XModule mas o XModule não exporta o XComponent .

Veja também

  • Por que o módulo carregado lento tem que importar commonModule? Angular 2

  • Perguntas frequentes sobre o módulo angular

  • Qual é a diferença entre declarações, provedores e importação no NgModule

Você tem que export lo do seu NgModule :

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

Note que para criar um chamado “feature module”, você precisa importar o CommonModule dentro dele. Então, o código de boot do seu módulo ficará assim:

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

Mais informações disponíveis aqui: https://angular.io/guide/ngmodule#create-the-feature-module

O que você quiser usar de outro módulo, basta colocá-lo no array de exportação . Como isso-

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

RESOLVIDO COMO USAR UM COMPONENTE DECLARADO EM UM MÓDULO EM OUTRO MÓDULO.

Baseado na explicação de Royi Namir (Muito obrigado). Há uma parte ausente para reutilizar um componente declarado em um módulo em qualquer outro módulo enquanto o carregamento lento é usado.

1º: exportar o componente no módulo que o contém:

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

2º: no módulo em que você deseja usar o 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{} 

Assim o segundo módulo importa o primeiro módulo que importa e exporta o componente.

Quando importamos o módulo no segundo módulo, precisamos exportá-lo novamente. Agora podemos usar o primeiro componente no segundo módulo.