web-dev-qa-db-ger.com

Winkel 2 Verwenden Sie eine Komponente aus einem anderen Modul

Ich habe die Angular 2 (Version 2.0.0 - final) App mit angle-cli erstellt. 

Wenn ich eine Komponente erstelle und sie in das Deklarations-Array von AppModule einfüge, ist alles gut, es funktioniert. 

Ich entschied mich, die Komponenten zu trennen, also erstellte ich eine TaskModule und eine Komponente TaskCard. Jetzt möchte ich die TaskCard in einer der Komponenten der AppModule (der Board-Komponente) verwenden.

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

Das gesamte Projekt ist auf https://github.com/evgdim/angular2 (Kanban-Board-Ordner) verfügbar.

Was fehlt mir? Was muss ich tun, um TaskCardComponent in BoardComponent zu verwenden?

138
Evgeni Dimitrov

Die Hauptregel hier ist, dass:

Die Selektoren, die beim Kompilieren einer Komponentenvorlage anwendbar sind, werden vom Modul bestimmt, das diese Komponente deklariert, und vom vorübergehenden Abschluss der Exporte der Importe dieses Moduls.

Also, versuchen Sie es zu exportieren:

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

Was soll ich exportieren?

Exportieren Sie deklarierbare Klassen, auf die Komponenten in anderen Modulen in ihren Vorlagen verweisen können sollen. Dies sind Ihre öffentlichen Klassen. Wenn Sie eine Klasse nicht exportieren, bleibt sie privat und nur für andere in diesem Modul deklarierte Komponenten sichtbar.

In dem Moment, in dem Sie ein neues Modul erstellen, ob faul oder nicht, ein neues Modul und Sie deklarieren irgendetwas darin, hat dieses neue Modul einen sauberen Zustand (as Ward Bell sagte in https://devchat.tv/adv-in-angular/119-aia-avoiding-common-pitfalls-in-angular2 )

Winkel erzeugt transitives Modul für jedes von @NgModules.

Dieses Modul sammelt Direktiven, die entweder von einem anderen Modul importiert wurden (wenn das transitive Modul des importierten Moduls Direktiven exportiert hat) oder im aktuellen Modul deklariert wurden.

Wenn angular Vorlage kompiliert, die zum Modul X gehört, werden die Anweisungen verwendet, die in X.transitiveModule.directives gesammelt wurden.

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

Auf diese Weise gemäß obigem Bild

  • YComponent kann ZComponent nicht in seiner Vorlage verwenden, da directives ein Array von Transitive module Y enthält ZComponent nicht, weil YModuleZModule nicht importiert hat, dessen transitives Modul ZComponent im Array exportedDirectives enthält.

  • Innerhalb der Vorlage XComponent können wir ZComponent verwenden, weil Transitive module X verfügt über ein Direktiven-Array, das ZComponent enthält, da XModule ein Modul (YModule) importiert, das ein Modul (ZModule) exportiert, das eine Direktive ZComponent exportiert.

  • In der Vorlage AppComponent können wir XComponent nicht verwenden, da AppModuleXModule importiert, XModule jedoch nicht exportiert XComponent .

Siehe auch

317
yurzui

Sie müssen export von Ihrer NgModule aus:

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

(Winkel 2 - Winkel 6)

Komponente kann nur in einem einzelnen Modul deklariert werden ..__ Um eine Komponente aus einem anderen Modul verwenden zu können, müssen Sie zwei einfache Aufgaben ausführen:

  1. Exportieren Sie die Komponente im ersten Modul
  2. Importieren Sie das erste Modul in das zweite Modul

1. Modul:  

Haben Sie eine Komponente (nennen wir sie "ImportantCopmonent"), möchten wir sie auf der Seite des zweiten Moduls erneut verwenden.

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

Verwendet das "ImportantCopmonent" durch Importieren des FirstPageModule erneut

@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

Beachten Sie, dass Sie zum Erstellen eines sogenannten "Feature-Moduls" CommonModule darin importieren müssen. Ihr Modulinitialisierungscode sieht also so aus: 

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

Weitere Informationen finden Sie hier: https://angular.io/guide/ngmodule#create-the-feature-module

1
nostop

Gelöst, wie ein in einem Modul angegebenes Bauteil in einem anderen Modul verwendet wird.

Basierend auf der Erklärung von Royi Namir (Vielen Dank). Ein Teil fehlt, um eine in einem Modul deklarierte Komponente in einem anderen Modul wiederzuverwenden, während Lazy Loading verwendet wird. 

1. Exportieren Sie die Komponente in das Modul, das sie enthält:

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

2.: In dem Modul, in dem Sie TaskCardComponent verwenden möchten:

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

So importiert das zweite Modul das erste Modul, das die Komponente importiert und exportiert.

Wenn wir das Modul in das zweite Modul importieren, müssen wir es erneut exportieren. Jetzt können wir die erste Komponente im zweiten Modul verwenden.

0
christianAV

@yurzui du hast die richtige lösung und danke für die erklärung.

Ich hatte das Problem und diese Zeile:

exportiert: [Component] hat es gelöst.

0

Ein großer und guter Ansatz ist das Laden des Moduls aus einer NgModuleFactory. Sie können ein Modul in ein anderes Modul laden, indem Sie Folgendes aufrufen:

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);
    });
}

Ich habe das von hier bekommen.

0
Gaspar

Was auch immer Sie von einem anderen Modul verwenden möchten, legen Sie es einfach in das export-Array

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