I have Angular 2 (version 2.0.0 - final) app generated with angular-cli.
When I create a component and add it to AppModule
's declarations array it's all good, it works.
I decided to separate the components, so I created a TaskModule
and a component TaskCard
. Now I want to use the TaskCard
in one of the components of the AppModule
(the Board
component).
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)
What I'm missing? What I have to do to use TaskCardComponent
in BoardComponent
?
Whatever you want to use from another module, just put it in the export array. Like this-
You have to
export
it from yourNgModule
:Note that in order to create a so called "feature module", you need to import
CommonModule
inside it. So, your module initialization code will look like this:More information available here: https://angular.io/guide/ngmodule#create-the-feature-module
SOLVED HOW TO USE A COMPONENT DECLARED IN A MODULE IN OTHER MODULE.
Based on Royi Namir explanation (Thank you so much). 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:
2nd: In the module where you want to use TaskCardComponent:
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.
One big and great approach is to load the module from a
NgModuleFactory
, you can load a module inside another module by calling this:I got this from here.
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:
What should I export?
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)
Angular creates transitive module for each of
@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.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 useZComponent
in its template becausedirectives
array ofTransitive module Y
doesn't containZComponent
becauseYModule
has not importedZModule
whose transitive module containsZComponent
inexportedDirectives
array.Within
XComponent
template we can useZComponent
becauseTransitive module X
has directives array that containsZComponent
becauseXModule
imports module (YModule
) that exports module (ZModule
) that exports directiveZComponent
Within
AppComponent
template we can't useXComponent
becauseAppModule
importsXModule
butXModule
doesn't exportsXComponent
.See also
why lazy loaded module has to import commonModule? Angular 2
Angular Module FAQs