J'ai Angular 2 (version 2.0.0 - finale) application générée avec angular-cli.
Lorsque je crée un composant et que je l'ajoute au tableau de déclarations de AppModule
, tout fonctionne bien.
J'ai décidé de séparer les composants. J'ai donc créé une TaskModule
et un composant TaskCard
. Maintenant, je veux utiliser la TaskCard
dans l’un des composants de la AppModule
(la composante 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 { }
Module de tâches:
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{}
L'ensemble du projet est disponible sur https://github.com/evgdim/angular2 (dossier kanban-board)
Qu'est-ce que je manque? Ce que je dois faire pour utiliser TaskCardComponent
dans BoardComponent
?
La règle principale ici est que:
Les sélecteurs applicables lors de la compilation d'un modèle de composant sont déterminés par le module qui déclare ce composant et par la fermeture transitive des exportations des importations de ce module.
Alors, essayez de l'exporter:
@NgModule({
declarations: [TaskCardComponent],
imports: [MdCardModule],
exports: [TaskCardComponent] <== this line
})
export class TaskModule{}
Que devrais-je exporter?
Exportez les classes déclarables que les composants des autres modules doivent être capable de faire référence dans leurs modèles. Ce sont vos cours publics . Si vous n'exportez pas de classe, elle reste privée, visible uniquement pour les autres composant déclaré dans ce module.
Dès que vous créez un nouveau module, qu'il soit paresseux ou pas, n'importe quel nouveau module et que vous déclarez quoi que ce soit dedans, ce nouveau module a un état propre (comme Ward Bell l'a dit dans https://devchat.tv/adv-in-angular/119-aia-avoiding-common-pitfalls-in-angular2 )
Angular crée le module transitif pour chacun des @NgModule
s.
Ce module collecte les directives importées d'un autre module (si le module transitif du module importé comporte des directives exportées) ou déclarées dans le module actuel.
Lorsque angular compile un modèle appartenant au module X
, il utilise les directives collectées dans 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 cette façon selon la photo ci-dessus
YComponent
ne peut pas utiliser ZComponent
dans son modèle car le tableau directives
de Transitive module Y
ne contient pas ZComponent
car YModule
n'a pas importé ZModule
dont le module transitif contient ZComponent
dans exportedDirectives
.
Dans XComponent
template, nous pouvons utiliser ZComponent
car Transitive module X
contient un tableau de directives contenant ZComponent
car XModule
importe le module (YModule
) qui exporte le module (ZModule
) qui exporte la directive ZComponent
Dans le modèle AppComponent
, nous ne pouvons pas utiliser XComponent
car AppModule
imports XModule
mais XModule
n'exporte pas XComponent
.
Voir également
Vous devez export
partir de votre NgModule
:
@NgModule({
declarations: [TaskCardComponent],
exports: [TaskCardComponent],
imports: [MdCardModule],
providers: []
})
export class TaskModule{}
(Angulaire 2 - angulaire 6)
Le composant ne peut être déclaré que dans un seul module . Pour utiliser un composant d'un autre module, vous devez effectuer deux tâches simples:
1er module:
Avoir un composant (appelons-le: "ImportantCopmonent"), nous voulons le réutiliser dans la page du 2nd Module.
@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 { }
2ème module:
Réutilise "ImportantCopmonent" en important le FirstPageModule
@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 { }
Notez que pour créer un "module de fonctionnalité", vous devez importer CommonModule
à l'intérieur. Votre code d’initialisation de module ressemblera à ceci:
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 { }
Plus d'informations disponibles ici: https://angular.io/guide/ngmodule#create-the-feature-module
RESOLU COMMENT UTILISER UN COMPOSANT DÉCLARÉ DANS UN MODULE DANS UN AUTRE MODULE.
Basé sur l'explication de Royi Namir (merci beaucoup). Il manque une pièce pour réutiliser un composant déclaré dans un module dans un autre module lors du chargement différé.
1er: Exporter le composant dans le module qui le contient:
@NgModule({
declarations: [TaskCardComponent],
imports: [MdCardModule],
exports: [TaskCardComponent] <== this line
})
export class TaskModule{}
2nd: Dans le module où vous souhaitez utiliser 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{}
Ainsi, le deuxième module importe le premier module qui importe et exporte le composant.
Lorsque nous importons le module dans le deuxième module, nous devons l'exporter à nouveau. Nous pouvons maintenant utiliser le premier composant du deuxième module.
@yurzui vous avez la bonne solution et merci pour l'explication.
J'ai eu le problème et cette ligne:
exportations: [Composant] l'a résolu.
Une approche intéressante consiste à charger le module à partir d'une NgModuleFactory
. Vous pouvez charger un module dans un autre module en appelant ceci:
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);
});
}
Je viens de ici .
Tout ce que vous voulez utiliser depuis un autre module, mettez-le simplement dans le tableau export .
@NgModule({
declarations: [TaskCardComponent],
exports: [TaskCardComponent],
imports: [MdCardModule]
})