2016-05-22 68 views
2

我有一项服务。 在构造函数中:从Angular 2服务中消费Json文件

export class Service { 

    _data: any 

    constructor(private http: Http) { 
    this.http 
     .get('../assets/my_json_file.json') 
     .map(x => x.json()) 
     .subscribe((data) => 
     this._data = data 
    ) 
    console.log(this._data) 
    } 

console.log回报undefined虽然它的数据显示,如果console.log移入传递给subscribe功能。

我的目标是拥有一批在服务,由应用程序调用的函数getStuff()ngOnInit与下拉菜单和东西值

this但没有帮助找出什么地方出了错

+1

你不能像那样使用它。 * http *是异步的,你想同步使用它。 您可以在服务中具有* getStuff *函数,但您需要在数据准备好时开始调用这些函数,这可以通过在应用程序组件中添加另一个订阅者来完成。 所以它没关系,它是一个* json *,数据是用与服务器相同的* http *获取的。 – tibbus

回答

5

this.http.get('../assets/my_json_file.json')是异步的,这意味着对服务器的调用计划在稍后执行,并且当服务器的响应最终到达时,传递给.subscribe(...)的回调将与响应一起被调用。 “预定”意味着任务将被添加到事件队列中,以便在先前计划的任务完成时稍后执行。

http.get(...)拨打电话后,预定console.log(this._data)将被执行。这是甚至在启动服务器的调用之前。

http.get(...)调用也仅在由0123aa返回的observable订阅时计划,因为observables是懒惰的。

使用的map(...)代替subscribe(...)返回一个Observable代替Subscription,让你的服务的用户链它自己的代码来响应事件。

@Injectable() 
export class Service { 

    _data: any 

    constructor(private http: Http) {} 

    getData() { 
    this.http 
     .get('../assets/my_json_file.json') 
     .map(x => x.json()) 
     .map((data) => 
     this._data = data 
    ) 
    console.log(this._data) 
    } 
} 

在一个组件,您可以使用它像

export class MyComponent { 
    constructor(service:Service) { 
    // `subscribe` actually initiates the call to the server 
    service.getData().subscribe(result => console.log(result)); 
    } 
} 

参见What is the correct way to share the result of an Angular 2 Http network call in RxJs 5?

这样,你已经可以开始在该服务实例化服务器的号召,不仅后使用服务订阅的组件。