web-dev-qa-db-fra.com

Angular 2 Utiliser le composant d'un autre module

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?

138
Evgeni Dimitrov

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 @NgModules. 

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

 enter image description here

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

284
yurzui

Vous devez export partir de votre NgModule:

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

(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:

  1. Exporter le composant dans le premier module
  2. Importer le premier module, dans le deuxième module

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 { }
3
Eyal c

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

1
nostop

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.

0
christianAV

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

0
Nasser Albelbeisi

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 .

0
Gaspar

Tout ce que vous voulez utiliser depuis un autre module, mettez-le simplement dans le tableau export

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