Json 角度2中可观测的http无法使用数据

Json 角度2中可观测的http无法使用数据,json,angular,typescript,observable,angular-cli,Json,Angular,Typescript,Observable,Angular Cli,我对angular 2和observables是新手,但我想尝试一下。因此,我安装了angular cli并制作了一个简单的测试项目 我想要它做的只是读取一个json文件,并处理组件内部的数据(最初的目的是创建一个服务,但我希望从一个较低的基础开始) 因此,我在assets/json文件夹(testjson.json)中创建了一个json文件: 然后我从angular导入了http,并在content.component.ts文件中导入了rxjs映射内容: import { Component,

我对angular 2和observables是新手,但我想尝试一下。因此,我安装了angular cli并制作了一个简单的测试项目

我想要它做的只是读取一个json文件,并处理组件内部的数据(最初的目的是创建一个服务,但我希望从一个较低的基础开始)

因此,我在assets/json文件夹(testjson.json)中创建了一个json文件:

然后我从angular导入了http,并在content.component.ts文件中导入了rxjs映射内容:

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]
但是我想在整个组件中使用这些数据,而不仅仅是在构造函数中。但是如果我尝试在构造函数外部(在ngOnInit函数内部)记录console.log“this.data”,它会在控制台中打印未定义的内容

我知道,这一定与异步加载有关,但不幸的是,我不知道如何告诉应用程序等待,直到这个.data被填充

我希望你能帮我。当然,在未来,我希望有一个服务可以做这类事情,并且不止一个组件应该从中获取数据

提前谢谢

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

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

编辑 对于下面的注释,如果您将http调用抽象为服务,您可以看到完全相同的逻辑仍然适用。您仍然在使用数据承诺的概念,一旦承诺完成,您就可以订阅该承诺。这里唯一的区别是http调用被抽象为不同的类

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);
      });
  }
}
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});
  }
导出类内容服务{
构造函数(专用http:http){
}
getData():IObservable{//,其中字符串可以是某个定义的类型
返回http.get('assets/json/testjson.json')
.map(res=>res.json()为{teststring:string});
}

首先将异步代码从构造函数移动到ngOnInit()。您的数据在promise is resolvedok之后可用。谢谢,但console.log只是为了快速测试数据是否存在。假设我有一个服务,持有此.data,我想从组件调用该服务的getter来获取数据并打印测试字符串。只要异步请求正在运行,getter就无法交付测试字符串数据不完整。因此,如果我在组件内部调用getter,服务将提供未定义的数据。我如何才能等待服务填充此数据?@sonnenpriester-与您现在所做的完全相同。您从服务返回一个IObservable,该服务承诺提供数据,并从组件订阅它。两者之间的唯一区别是上面的de和添加服务是对服务的
http
调用的抽象。@sonnenpriester-我添加了另一个服务示例。正如您所看到的,概念没有改变,您使用承诺做某事,然后订阅该承诺,在承诺完成后执行某事。这是否意味着我们有一个请求从服务中获取数据的每个组件?我的意图是服务发出一个请求并将数据存储在此中。数据和所有组件只需调用一个getter即可获取存储在此中的数据。数据来自服务。@sonnenpriester-您可以将数据结果作为变量缓存在服务中。然后组件将检查服务中是否存在数据,如果数据尚未初始化,则以与上面编写的代码相同的方式调用该方法。
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});
  }