2016-06-19 16 views
0

Ich versuche, mit 2.0.0-beta.17 in angular2 zu kommen. Ich möchte Daten von einem Dienst lesen, aber egal was ich tue, erhalte ich eine Ausnahme:Kein Provider für Service

No provider for LanguageBrowser! 

Ich ging durch Dutzende von den gleichen Fragen hier aber keiner von ihnen arbeitete.

Das ist meine Dienstklasse:

import {Injectable} from "angular2/core"; 
import {Language} from "../models/language.model"; 

@Injectable() 
export class LanguageService { 
    ReadAll(onNext: (json: any) => void) { 
     return [ 
      new Language({ Id: 1, Name: "German" }), 
      new Language({ Id: 2, Name: "English" }), 
      new Language({ Id: 3, Name: "Dutch" }) 
     ]; 
    } 
} 

Sprache ist eine einfache Typoskript-Klasse, die von einem Webservice Aufruf am Ende abgerufen werden sollte, aber ich bin nicht so weit.

export class Language { 
    public Id: number; 
    public Name: string; 

    constructor(json: any) { 
     if (json) { 
      this.Id = json.Id || 0; 
      this.Name = json.Name || ""; 
     } 
    } 
} 

Die Sprachenservice von einem LanguageBrowser Komponente verbraucht wird

import {Component} from "angular2/core" 
import {Language} from "../models/language.model" 
import {LanguageDetail} from "./language-detail.component" 
import {LanguageCollection} from "./language-collection.component" 
import {LanguageService} from "../services/language.service" 

@Component({ 
    selector: "language-browser", 
    template: ` 
     <language-collection [languages]="availableLanguages" (selectionChanged)="onSelectionChanged($event)"></language-collection> 
     <language-detail [language]="selectedLanguage"></language-detail> 
    ` 
    providers: [LanguageService], 
    directives: [LanguageCollection, LanguageDetail] 
}) 
export class LanguageBrowser { 
    private selectedLanguage: Language; 
    private availableLanguages: Language[]; 

    constructor(languageService: LanguageService) { 
     languageService.ReadAll(json => this.availableLanguages = json); 
    } 

    onSelectionChanged(language) { 
     this.selectedLanguage = language; 
    } 
} 

LanguageCollection ist eine weitere Komponente, die eine Liste der Sprachen, und Emittieren eines Ereignisses nimmt auf in der Liste eine der Sprachen ausgewählt wird. LanguageDetail zeigt einfach die ausgewählte Sprache an. Sie sind beide irrelevant (ich nehme an), also werde ich sie hier ausschließen.

Als eine andere Antwort vorgeschlagen habe ich System-Polyfills.js und es6-shim.js hinzugefügt, wie Skript enthält, aber ohne Erfolg. Dies ist der relevante Teil meines Layout:

<script src="~/js/jquery.js"></script> 
<script src="~/js/bootstrap.js"></script> 
<script src="~/js/system.js"></script> 
<script src="~/js/system-polyfills.js"></script> 
<script src="~/js/rx.js"></script> 
<script src="~/js/typescript.js"></script> 
<script src="~/js/es6-shim.js"></script> 
<script src="~/js/angular2/angular2-polyfills.js"></script> 
<script src="~/js/angular2/angular2.dev.js"></script> 
<script src="~/js/angular2/http.dev.js"></script> 
<script src="~/js/angular2/router.dev.js"></script> 

<script> 
     System.config({ 
      packages: { 
       app: { 
        format: 'register', 
        defaultExtension: 'js' 
       } 
      } 
     }); 
     System.import('app/boot'); 
</script> 

Mit Boot einfach wie folgt aussehen:

import {bootstrap} from "angular2/platform/browser" 
import {AppComponent} from "./app.component" 
import "rxjs/add/operator/map"; 

bootstrap(AppComponent); 

Und AppComponent wie folgt aus:

import {Component} from "angular2/core"; 
import {LanguageBrowser} from "./components/language-browser.component"; 

@Component({ 
    selector: "app", 
    template: ` 
     <language-browser></language-browser> 
    `, 
    directives: [LanguageBrowser] 
}) 

export class AppComponent { 
    public LanguageBrowser: LanguageBrowser; 

    constructor(languageBrowser: LanguageBrowser) { 
     this.LanguageBrowser = languageBrowser; 
    } 
} 

Die Abhängigkeiten in meinem package.json:

"dependencies": { 
    "angular2": "2.0.0-beta.17", 
    "bootstrap": "3.3.6", 
    "es6-promise": "3.2.1", 
    "es6-shim": "0.35.1", 
    "jquery": "2.2.4", 
    "reflect-metadata": "0.1.2", 
    "rxjs": "5.0.0-beta.6", 
    "systemjs": "0.19.30", 
    "typescript": "1.8.10", 
    "zone.js": "0.6.12" 
    }, 
    "devDependencies": { 
    "gulp": "3.9.1", 
    "del": "2.2.0" 
    }, 
    "peerDependencies": { 
    "reflect-metadata": "0.1.2", 
    "rxjs": "5.0.0-beta.6" 
    } 

Als npm ins tallation sagte mir angular2 will peerDependencies von reflect-metadata und rxjs habe ich sie einfach als peerDependencies aufgenommen. Ich hatte sie auch als regelmäßige Abhängigkeiten ohne Veränderung.

Offensichtlich vermisse ich etwas, aber ich kann nicht herausfinden, was es sein könnte. Ging durch mehrere Tutorials für angular2, aber keiner von ihnen hat den Trick gemacht.

+0

Was versuchen Sie mit der injizierten Komponente? – rinukkusu

+0

Wenn Sie nur die Komponente anzeigen möchten, dann entfernen Sie die Konstruktorinjektion in der 'AppComponent', da Sie den LanguageBrowser bereits in Ihrem' [Richtlinien] ' – rinukkusu

+0

@rinukkusu laden Wie kann ich dann darauf zugreifen, um die Sprachen zu lesen? –

Antwort

3

Verwendung ViewChild:

@Component({ 
    selector: "app", 
    template: ` 
     <language-browser></language-browser> 
    `, 
    directives: [LanguageBrowser] 
}) 

export class AppComponent { 
    @ViewChild(LanguageBrowser) lb:LanguageBrowser; 

    constructor() {} 
    ngAfterViewInit() { 
     let yey = this.lb.availableLanguages; 
    } 
} 

Versuchen Sie auch, etwas zu tun, in den Konstruktor zu vermeiden, lernen lifecycle hooks und nutzen sie statt.

+0

Ich kann eigentlich nicht sehen, wie mir das bei meinem Fehler helfen könnte. Sie berühren nicht einmal die LanguageBrowser-Komponente, die den Fehler verursacht, dass der Provider fehlt. Außerdem benötige ich nicht die verfügbaren Sprachen in meiner AppComponent, also bin ich mir nicht sicher, was Sie hier erreichen wollen. Wie auch immer, ich lese auf Lifecycle-Hooks, wie du es vorgeschlagen hast und auch auf DI und ich habe jetzt eine funktionierende Lösung gefunden, also danke trotzdem. –

+0

Was ist schlecht am Injizieren im Konstruktor? –

+0

Im Konstruktor untergeordnete Komponente noch nicht vorhanden, siehe [dieser Plotter] (http://plnkr.co/edit/WH6FZfLSeSWrYKgJiZaN?p=preview). Sie haben auch versucht, eine Komponente zu injizieren, und das wird nicht funktionieren - Sie injizieren Klassen, die mit '@Injectable()' dekoriert sind, andere importieren und typischerweise in Lebenszyklus-Hooks verwenden ... – Sasxa

1

Nach dem Vorschlag von Sasxa, Lebenszyklus-Haken und seinen Link zu lernen, war ich tatsächlich in der Lage, eine Lösung zu finden. Ich bin mir ziemlich sicher, dass es ein halbes Dutzend einfacherer Möglichkeiten gibt, dies zu tun, aber abgesehen davon, dass ich den LanguageService in den Konstruktor einfüge, kann ich nicht herausfinden, wie ich das Serviceobjekt in die Finger bekomme.

Wie auch immer, das ist, was ich tue jetzt:

import {Component, OnInit, ReflectiveInjector} from "angular2/core" 
import {Language} from "../models/language.model" 
import {LanguageDetail} from "./language-detail.component" 
import {LanguageCollection} from "./language-collection.component" 
import {LanguageService} from "../services/language.service" 

@Component({ 
    selector: "language-browser", 
    templateUrl: "./app/views/language-browser.html", 
    providers: [LanguageService], 
    directives: [LanguageCollection, LanguageDetail] 
}) 
export class LanguageBrowser implements OnInit { 
    private selectedLanguage: Language; 
    private availableLanguages: Language[]; 

    ngOnInit() { 
     var injector: ReflectiveInjector = ReflectiveInjector.resolveAndCreate([LanguageService]); 
     var languageService: LanguageService = injector.get(LanguageService); 

     this.availableLanguages = languageService.ReadAll(); 
    } 

    onSelectionChanged(language) { 
     this.selectedLanguage = language; 
    } 
} 

Wenn jemand eine Erklärung, warum der Fehler hat zunächst aufgetreten ich froh sein würde, es zu hören.

Verwandte Themen