2016-05-24 10 views
1

Ich lehre mich gerade Angular2 und habe ein paar Kinderkrankheiten (um es gelinde auszudrücken). Wie auch immer, ich möchte einen Service erstellen, der eine statische JSON-Datei lädt. Zur Zeit verwende ich i18n-Dateien, da sie JSON strukturiert haben. Der Dienst wird auch eine Methode haben, die einen übergebenen Parameter (ein Argument) annimmt und dann nach der JSON-Eigenschaft mit dem Namen des übergebenen Parameters sucht. recht einfach klingt, aber ich habe ein paar Fragen, zunächst einmal alles hier ist mein Dienst, den ich imaginär Contentservice genannt, ist die Datei content.service.tsAngular2-Dienst zum Laden von JSON und zum Zurückgeben bestimmter JSON-Knoten/-Eigenschaften

import { Injectable } from '@angular/core'; 
import { Http, Response } from '@angular/http' 

@Injectable() 
export class ContentService { 

    loadedContent: any; // will create a real type later 

    constructor(private http: Http) { 

     // 1. Determine the language 
     let userLang:string = navigator.language.split('-')[ 0 ]; 
     userLang = /(en|de)/gi.test(userLang) ? userLang : 'en'; 

     // 2. Load the file... I should really use interpolation for the file path 
     this.http.get('src/i18n/' + userLang + '.json').map((res:Response) => res.json()).subscribe(res => this.loadedContent = res); 
    } 

    getContent(selector) { 

     // in here we need to pass the selector and fetch the content from the loaded JSON, however for now I will just return the passed selector and see if I have access to the loadedConent 
     console.log(selector, this.loadedContent); // this.loadedContent is undefined! 
     // we need a catch for we the selector is not found.... 
    } 
} 

in einer anderen Komponente ich den Dienst importieren ...

import { ContentService } from '../content/content.service'; 

@Component({ 
    selector: 'angular2-test', 
    providers: [ ContentService ], 
    templateUrl: 'src/home/home.template.html' 
}) 

export class TestComponent { 

    content: any; // real type to come later 

    constructor(private contentService: ContentService) { 
     this.content = this.contentService.getContent('promotion') 
    } 
} 

Jetzt habe ich natürlich ein bisschen einen Fehler, wie in meiner getContent-Methode habe ich keinen Zugriff auf this.loadedContent und in der Konsole Ich gebe "" zurück. Wie kann ich meine Methode erhalten, Zugriff auf die loadedContent Eigenschaft meines Service zu haben?

BTW: Dies ist der Inhalt meiner statischen JSON-Datei ist, und es wird in den Dienst ...

{ 
    "promotion": { 
    "pageTitle": "Oh we have a lovely promotion today..." 
    } 
} 

Vielen Dank im Voraus geladen!

Antwort

3

Ich würde überarbeiten Sie da es asynchron zu machen:

import {Observable} from 'rxjs/Rx'; 

@Injectable() 
export class ContentService { 
    loadedContent: any; // will create a real type later 
    obs: Observable<any>; 

    constructor(private http: Http) { 
    let userLang:string = navigator.language.split('-')[ 0 ]; 
    userLang = /(en|de)/gi.test(userLang) ? userLang : 'en'; 

    this.obs = this.http.get('src/i18n/' + userLang + '.json') 
     .map((res:Response) => res.json()) 
     .do(res => this.loadedContent = res); 
    } 

    getContent(selector) { 
    if (this.loadedContent) { 
     return Observable.of(this.loadedContent); 
    } else { 
     return this.obs; 
    } 
    } 
} 

und es auf diese Weise in der Komponente verwenden:

@Component({ 
    selector: 'angular2-test', 
    providers: [ ContentService ], 
    templateUrl: 'src/home/home.template.html' 
}) 
export class TestComponent { 
    content: any; // real type to come later 

    constructor(private contentService: ContentService) { 
    this.contentService.getContent('promotion').subscribe(content => { 
     this.content = content; 
    }); 
    } 
} 

Eine weitere Option auch asynchron Ihre Anwendung Bootstrap sein könnte. Sehen Sie diese Frage für weitere Informationen:

+2

Danke, aber ich nehme an ich brauche eine Art zu geben this.obs zu/erklären es an der Spitze meines Dienstes? Ich muss auch Observable von RxJS importieren –

+0

Gern geschehen! Ja, es könnte 'Observable sein ' ... –

+0

Großartig, danke für den Link auch! Ich bekomme eine Warnung über 'ungelöste Methode oder Funktion von()', aber ich kann damit leben, jetzt kann ich den Code schreiben, um den gewünschten Knoten zurückzugeben (der tatsächliche JSON ist viel größer)! Danke vielmals! –

Verwandte Themen