2017-05-25 4 views
0

Ich habe ein Lazy-Loaded-Modul, das einen Dienst und eine Komponente hat.Komponente kann nicht Provider aus lazy-loaded Modul finden

Ich möchte den Dienst in dieser Komponente verwenden, aber ich bekomme:

Error: No provider for EventService! 

Das Modul

import { NgModule } from '@angular/core'; 
import { CommonModule } from '@angular/common'; 
import { EventRoutingModule } from './event-routing.module'; 

import { FormsModule } from '@angular/forms'; 
import { HttpModule } from '@angular/http'; 
import { EventListModule } from './../event-list/event-list.module'; 

import { ModuleWithProviders } from '@angular/core'; 

import { EventComponent } from './event.component'; 
import { EventService } from './event.service'; 

@NgModule({ 
    imports: [ 
     CommonModule, 
     FormsModule, 
     HttpModule, 
     EventRoutingModule, 
     EventListModule 
    ], 
    declarations: [EventComponent] 
}) 

export class EventModule { 

    static forRoot(): ModuleWithProviders { 
     return { 
      ngModule: EventModule, 
      providers: [EventService] 
     }; 
    } 

} 

die Komponente

import { Component, OnInit } from '@angular/core'; 
import { EventService } from './event.service'; 

@Component({ 
    templateUrl: './event.component.html', 
    styleUrls: ['./event.component.scss'] 
}) 
export class EventComponent implements OnInit { 


    private eventService: EventService; 

    constructor(eventService: EventService) { 
     this.eventService = eventService; 
    } 

    ngOnInit() { 
     this.eventService.getEvents().subscribe(data => console.log(data), error => console.log(error)); 
    } 

} 

der Service

import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import { AuthHttp } from 'angular2-jwt'; 

@Injectable() 
export class EventService { 
    private static readonly URL = 'http://localhost:3000/api/events'; 

    constructor(private authHttp: AuthHttp) { } 

    public getEvents() { 

     return this.authHttp.get(EventService.URL); 
    } 

} 

Ich habe hier ein paar Beiträge angeschaut, aber ich war nicht in der Lage, eine Lösung von ihnen zu bekommen.

Ich weiß Provider in Lazy-geladenen Modulen sind Modul-Bereich und Lazy-geladene Module haben ihre eigenen Abhängigkeitsbaum.

Aber es muss möglich sein, den Anbieter in die Komponente zu injizieren, nicht wahr?

Antwort

1

Sie müssen definieren, wie Sie Ihren Service bereitstellen.

Sie können festlegen, wie es am Modulebene vorgesehen ist:

@NgModule({ 
    imports: [ 
     CommonModule, 
     FormsModule, 
     HttpModule, 
     EventRoutingModule, 
     EventListModule 
    ], 
    declarations: [EventComponent], 
    providers: [EventService] 
}) 
export class EventModule { ... } 

Dies bedeutet, dass eine EventService Instanz für das gesamte Modul zur Verfügung stehen wird.

Oder am Komponentenebene:

@Component({ 
    templateUrl: './event.component.html', 
    styleUrls: ['./event.component.scss'], 
    providers [EventService] 
}) 
export class EventComponent implements OnInit { ... } 

Dies bedeutet, dass eine EventService Instanz für jede Komponenteninstanz zur Verfügung steht. Dies liegt an der Funktion der hierarchischen Injektoren. Die Komponente definiert einen eigenen Injektor, der eigene Instanzen enthalten kann, die seinen Kindern zur Verfügung gestellt werden.

[EventService] entspricht [ { provide: EventService, useClass: EventService }]. Dies bedeutet, dass der Schlüssel zum Eingeben der Abhängigkeit EventService ist und die Instanz mithilfe des Konstruktors EventService erstellt wird.

+0

Warum funktioniert es nicht mit forRoot? Ich dachte im Falle von Lazy-Loaded-Modulen, sollten Sie forRoot verwenden? – user3629892

+0

'forRoot()' dient zum Konfigurieren der Routen auf Root-Ebene. 'forChildren()' ist gut, wenn Sie die Routing-Konfiguration pro Modul aufteilen. In der Regel wird empfohlen, für jedes Modul ein separates Modul zu verwenden, das das Routing konfiguriert. Das entsprechende Modul, das das Routing konfiguriert, wird 'forChildren()' verwenden. Auf der anderen Seite kann die Routing-Eigenschaft 'loadChildren' verwendet werden, um ein Modul async zu laden, wenn eine Route erreicht wird. – andreim

+0

Daher haben Sie in Ihrem Fall 'EventModule', Sie können ein separates 'EventRoutingModule'-Modul haben, das' forChildren() 'verwendet, um die Routing-Konfiguration zu laden, wenn das Modul geladen wird. – andreim