web-dev-qa-db-fra.com

angular2 - Comment fonctionnent les "importations" et les "exportations" dans les modules Angular2?

Je suis complètement nouveau dans Angular2 et il a été très difficile de comprendre ce qui se passe avec le @NgModuleimportations et exportations dans Angular2.

Prenez le code suivant par exemple-:

@NgModule({
  imports: [
    RouterModule.forChild(heroesRoutes)
  ],
  exports: [
    RouterModule
  ]
})

Dans la section des importations qu'est-ce que j'importe?Le module de routeur, ou la fonction forChild (), ou le module renvoyé par la fonction forChild ()?

De même, lorsque j'exporte à nouveau RouterModule, la documentation dit ce qui suit-:

Notre dernière étape consiste à réexporter le RouterModule. En réexportant le fichier RouterModule, notre module de fonctions sera fourni avec le routeur Directives lors de l'utilisation de notre module de routage.

Cela signifie-t-il que quel que soit le module important le NgModule ci-dessus, aura accès à tout le code du RouterModule? 

Est-ce un peu comme si j'écrivais un fichier d'en-tête personnalisé en C qui incluait math.h, si je l'utilise maintenant, je n'ai plus besoin d'inclure math.h dans mon programme séparément. _ {Mon analogie est-elle correcte?

Quelqu'un peut-il expliquer les concepts de base ici, afin que je ne sois pas embarrassé à chaque fois que je vois un nouveau code.

23
ng.newbie

Un module dans Angular2 est très similaire aux modules Angular1, qui sont fondamentalement un paquet contenant tous les éléments qu'il est logique d’expédier ensemble.

Par exemple, si vous avez un LoginComponent qui, pour certaines raisons, est connecté à un service, LoginService, qui effectue une requête http pour obtenir des informations utilisateur, vous pouvez créer un LoginModule qui envoie ensemble LoginComponent et LoginService en tant que LoginModule.

LoginService pourrait également utiliser certaines interfaces, par exemple une interface utilisateur, ce qui, encore une fois, aurait du sens d'être expédié à LoginModule au consommateur.

Donc, si je suis votre client et que je vais utiliser votre fonctionnalité de connexion générale, il sera beaucoup plus facile pour moi d'importer simplement votre LoginModule et tous vos goodies disponibles pour mon AppComponent!

Ainsi, votre classe LoginModule (qui n’est autre qu’un simple fichier javascript et une fonction) doit exporter LoginModule pour que je puisse l’utiliser :).

LoginModule ressemblerait à ceci: 

   @NgModule({
      declaration:[LoginComponent , LogoutComponent], 
      exports: [
        LoginComponent , LogoutComponent
      ],
      providers:[LoginService]
    })
    export class LoginModule{

    }

Donc, dans mon AppModule, je voudrais importer votre LoginModule.

@NgModule({
  imports: [
    LoginModule,
    RouterModule.forChild(heroesRoutes) // another imported module that I need beside the Login
  ]
})

MAIS : 

Si je connais votre code et que je ne veux aucune de vos fonctions, composants, classes et choses supplémentaires et que je dois simplement utiliser votre LoginComponent, je préférerais peut-être simplement déclarer que j'utilise LoginComponent et je ne veux pas importez votre LoginModule massif!

@NgModule({
  declaration:[LoginComponent],
  imports: [
    RouterModule.forChild(heroesRoutes)
  ]
})

Cela ne fonctionnerait que si LoginComponent ne dépend pas directement de LoginService, sinon Angular se plaindrait et indiquerait:

**No Provider for LoginService**

Dans ce cas, si vous êtes une personne difficile et que vous n'êtes toujours pas convaincu d'utiliser LoginModule, vous pouvez aider Angular et fournir le LoginService comme suit: 

@NgModule({
  declaration:[LoginComponent],// declaring it 
  providers:[LoginService],// providing it
  imports: [
    RouterModule.forChild(heroesRoutes)
  ]
});

Ainsi, cela pourrait continuer et vous trouverez peut-être plus facile d'importer tout le LoginModule et de laisser le module faire tout le travail.!

C'est tout avec LoginModule.


Maintenant, pour répondre à votre question concernant forChild .

LoginModule peut vouloir faire des choses supplémentaires en vous donnant ses classes qui ne sont pas toujours nécessaires, dans ce cas, vous pourriez avoir amélioré le LoginModule et y ajouter du sucre.

@NgModule({
   declaration:[LoginComponent , LogoutComponent], 
   exports: [LoginComponent , LogoutComponent],
   providers:[LoginService]
})  
export class LoginModule{
  public static logAndLoadModule(message){
     console.log('I first log and then give you my module');
     return {
      ngModule: LoginModule
     }
  }
  public static alertAndLoadModule(message){
      alert('I first alert and then give you my module');
     return {
      ngModule: LoginModule
     }
  }
}

Ce qui, dans ce cas, ressemble à ce que le module peut enregistrer quelque chose quand il commence à me donner son paquet. Donc, je pourrais l'utiliser comme ça: 

   @NgModule({
      imports: [
        LoginModule.logAndLoadModule(),
        RouterModule.forChild(heroesRoutes)
      ]
    })

logAndLoadModule this n'est-il pas similaire à forChild function of RouterModule? 

Oui, c'est vrai, il vous donne toujours LoginModule mais il fait aussi quelque chose de plus. 

Vous pouvez donc toujours importer LoginModule, mais vous pouvez également utiliser son alerte et son journal.

METTRE À JOUR: 

export class LoginModule , signifie que le fichier actuel (probablement login.module.ts ou autre) exporte une classe appelée LoginModule qui peut être importée à partir d'autres fichiers et n'a rien à voir avec Angular, il s'agit uniquement de TypeScript qui va compiler en javascript.

Tandis que 

  @NgModule({
      exports: [
        LoginModulesBrother
      ]
    })
  export class LoginModule{

  }

Ci-dessus, le langage spécifique à Angular2 signifie que LoginModule exporte également LoginModulesBrother. Par conséquent, quiconque importe Importer LoginModule a également accès à LoginModulesBrother.

Donc, LoginModulesBrother, est un autre module qui est probablement défini ailleurs: 

  @NgModule({
      // some other magic here 
  })
  export class LoginModulesBrother{

  }

Donc, généralement, importer et exporter une class , qui pourrait être ce que jamais (un module, un composant, un tuyau, une fonction simple ou autre chose) est uniquement de typeScript, mais exporte un tableau et importe un tableau uniquement un langage spécifique à Angular et ne signifie rien à TypeScript.

35
Milad

Si vous utilisez le composant <router-outlet> ou les directives routerLink ou routerLinkActive, vous devez ajouter la variable RouterModule à imports: [] de chaque module où vous souhaitez utiliser l'un de ces éléments.

C'est la même chose pour n'importe quelle directive, composant ou pipe. Angular ne les instancie dans un module que s’ils sont connus par une importation.

Si vous ajoutez un module à imports: [], toutes les directives, les composants et les tuyaux répertoriés dans les exportations deviennent disponibles pour le module d'importation.

Un module peut également réexporter d'autres modules, ce qui rend toutes les directives, les composants et les canaux exportés de ces modules disponibles pour le module d'importation.

Voir également 

3
Günter Zöchbauer

Depuis le RouterModule docs:

  • forRoot crée un module contenant toutes les directives, les itinéraires donnés et le service de routeur lui-même.
  • forChild crée un module contenant toutes les directives et les itinéraires donnés, mais n'inclut pas le service de routeur.

Vous utilisez forRoot pour configurer le routage pour votre module racine et forChild pour vos modules de fonctions. 

Vous n'avez pas besoin de router service dans les modules de fonctions car vous n'en avez besoin que d'un seul pour votre application, que vous devez configurer dans AppRoutingModule par convention (en supposant que votre module racine s'appelle AppModule).

En utilisant votre extrait de code comme exemple:

    @NgModule({
      imports: [
        RouterModule.forChild(heroesRoutes)
      ],
      exports: [
        RouterModule
      ]
    })
   export class AppRoutingModule {}

RouterModule a des déclarations telles que routerLink ou routerLinkActive qui pourraient être utilisées par les composants de AppModule

Pour que ces déclarations soient disponibles dans AppModule, vous devez importer RouterModule directement dans AppModule ou le rendre disponible via AppRoutingModule en l'exportant. 

0
eosimosu