Angular 2中Observable的http无法使用数据

时间:2017-01-31 15:49:02

标签: json angular typescript observable angular-cli

我是角度2和观察者的新手,但我想试一试。所以我安装了angular-cli并做了一个简单的测试项目。

我想要它做的就是读取一个json文件并使用组件内部的数据(第一个目的是提供服务,但我想以较低的方式开始)。

所以我在assets / json文件夹(testjson.json)中创建了一个json文件:

{
  "teststring": "test works"
}

然后我从angular.component.ts文件中导入了angular和rxjs映射内容的http:

import { Component, OnInit } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

@Component({
  selector: 'app-content',
  templateUrl: './content.component.html',
  styleUrls: ['./content.component.css']
})
export class ContentComponent implements OnInit {

  title: string = "Default";
  data;

  constructor(private http:Http) {
    http.get('assets/json/testjson.json').map(res => res.json()).subscribe(data => {this.data = data; this.title = data.teststring; console.log(this.data);});
  }

  ngOnInit() {

  }

}

到目前为止,该应用程序打印出以下内容:

app works!

test works [object Object]

但我想在整个组件中使用这些数据,而不仅仅是在构造函数中。但如果我尝试console.log" this.data"在构造函数之外(在ngOnInit函数内),它在控制台中打印undefined。

我知道,它必须与asynch加载有关,但不幸的是我不知道如何告诉应用程序等到this.data被填满。

我希望你能帮助我。当然,在将来我想要一个服务来做这种事情,不止一个组件应该从中获取数据。

提前致谢!

1 个答案:

答案 0 :(得分:3)

  • 您应该将初始化代码移动到初始化方法。
  • 回调完成后,您的数据即可使用。在模板中,一旦有数据,您可以使用*ngIf在块内执行代码。只要*ngIf没有评估为真,内部代码就不会运行。
  • 运行console.log(data)的唯一方法是从回调内部或从回调中调用,因为您必须等到数据加载完毕。

<强> content.component.html

<div *ngIf="data">
  <span>{{data.teststring}}</span>
</div>

<强> content.component.ts

export class ContentComponent implements OnInit {

  title: string = "Default";
  data: any = null;

  constructor(private http:Http) {
  }

  ngOnInit() {
    this.http.get('assets/json/testjson.json')
      .map(res => res.json())
      .subscribe(data => {
        this.data = data;
        this.title = data.teststring;
        console.log(this.data);
      });
  }
}

修改

响应下面的评论如果您抽出对服务的http调用,您可以看到完全相同的逻辑仍然适用。您仍在使用数据承诺的概念,并且一旦完成,您就可以订阅该承诺。这里唯一的区别是http调用被抽象到另一个类。

<强> content.component.ts

export class ContentComponent implements OnInit {

  title: string = "Default";
  data: any = null;

  // inject service
  constructor(private contentService:ContentService) {
  }

  ngOnInit() {
    this.contentService.getData()
      .subscribe(data => {
        this.data = data;
        this.title = data.teststring;
        console.log(this.data);
      });
  }

<强>服务

export class ContentService {

  constructor(private http:Http) {
  }

  getData(): IObservable<{teststring:string}> { // where string can be some defined type
    return http.get('assets/json/testjson.json')
      .map(res => res.json() as {teststring:string});
  }