2017-02-11 55 views
2

我似乎無法設法使用來自json文件的信息製作視圖的變量,但我非常接近。我可以回顯.subscribe()鏈中的信息,但它不會將其設置爲變量,他們只是不確定,我做錯了什麼?如何正確提取Angular 2中的http.get中的JSON數據?

我只想將我的json文件加載到組件視圖中的變量中。這是很容易在角1

我的服務:

import { Injectable } from '@angular/core'; 
import { Http, Response, Headers, RequestOptions } from '@angular/http'; 
import 'rxjs/add/operator/map'; 
import {Observable} from 'rxjs/Rx'; 

@Injectable() 
export class GullkornService { 
result: any; 

constructor(private http:Http) { 
} 

getGullkorn() { 

let result = this.result; 
this.http.get('./gk/gullkorn.json') 
.map(res => res.json()) 
.subscribe(
     val => this.result = val, 
     err => console.error(err), 
     () => console.log(this.result)); // this one echoes out what i want 
     console.log(this.result); // but this one doesnt, so i cant return it 
     } 
} 

而且登陸組件:

import { Component, OnInit } from '@angular/core'; 
import {Router, RouterOutlet} from '@angular/router'; 
import { HttpModule, JsonpModule } from '@angular/http'; 
import { BrowserModule } from '@angular/platform-browser'; 
import { NgModule }  from '@angular/core'; 
import { GullkornService } from '../../gullkorn-service.service'; 
import { FormsModule } from '@angular/forms'; 
import {Observable} from 'rxjs/Observable'; 

import "gsap"; 
declare var ease, TimelineMax,TweenMax,Power4,Power1,Power2,Power3,Bounce, Elastic:any; 

@Component({ 
    selector: 'gullkorn-visning', 
    providers: [GullkornService], 
    templateUrl: './landing.component.html', 
    styleUrls: ['./landing.component.css'] 
}) 
export class LandingComponent implements OnInit { 
    gullkorn: any; 
    constructor(GullkornService: GullkornService) { 
     this.gullkorn = GullkornService.getGullkorn(); 
     console.log(this.gullkorn); 
    } 

    ngOnInit() { 
    } 

} 

基於當前的代碼,這是我所得到的:

result

我有這個項目:github

回答

2

這是一個異步操作,因此當您嘗試console.log時,結果是未定義的,因爲它在訂閱內的其他console.log之前運行。

.subscribe(
     val => this.result = val, 
     err => console.error(err), 
     () => console.log(this.result)); // is run sometimes later 
     console.log(this.result); // is run first 
     } 

我會作出一些改變你的代碼。我建議你照顧認購的組件,而不是,這是處理HTTP的請求的最佳方式。因此,只要map在服務和可觀察到的返回組件,記得要加return聲明:

getGullkorn() { 
    return this.http.get('./gk/gullkorn.json') 
    .map(res => res.json()) 
} 

在你的分量,我建議你移動你的服務呼叫OnInit代替。在這裏,您還可以注意到,根據代碼中的註釋,這些值不能在訂閱之外即時訪問。所以,如果你想以某種方式操縱你的數據,你需要考慮到這一點:)

ngOnInit() { 
    this.GullkornService.getGullkorn() 
    .subscribe(data => { 
    // is run sometimes later 
    this.gullkorn = data 
    }); 
    // is run first 
} 

,因爲這是一個異步操作,所以準備爲使用ngIf或視圖中的safe navigation operator,因爲在檢索數據之前呈現視圖。

因此,無論包裝你的代碼中ngIf

<div *ngIf="gullkorn"></div> 

{{gullkorn?.someProperty}}

+0

謝謝!這是第一次嘗試,對我來說這是一場鬥爭。欣賞你的時間很多。使用組件中的訂閱調用函數有訣竅! –

+1

不客氣!是的,我明白了。異步操作在開始時非常混亂!在我的回答中,還增加了更多的上下文。g如果您需要在導航到頁面時以某種方式操作組件中的數據,則需要注意訂閱中哪些數據可用,哪些不可用,認爲它對未來有用:)快速編碼! :) – Alex

1

這是更好地從服務返回的觀測和可訂閱它的組件:

服務:

@Injectable() 
export class GullkornService { 

    constructor(private http:Http) { 
    } 

    getGullkorn() { 
    // Return the observable here 
    return this.http.get('./gk/gullkorn.json') 
    .map(res => res.json()); 
    } 

} 

comp onent:

@Component({ 
    selector: 'gullkorn-visning', 
    providers: [GullkornService], 
    templateUrl: './landing.component.html', 
    styleUrls: ['./landing.component.css'] 
}) 
export class LandingComponent implements OnInit { 
    gullkorn: any; 
    constructor(GullkornService: GullkornService) { 
     GullkornService.getGullkorn() 
     .subscribe(
      val => this.gullkorn = val, 
      err => console.error(err) 
    } 

    ngOnInit() { 
    } 

} 
+0

謝謝!這就是我現在的做法。但即時通訊想知道一個新的東西,什麼時候該如何取消訂閱或者自動發生? –

+0

您可以在'ngOnInit'中訂閱,並在'ngOnDestroy'中取消訂閱 –