无法将JSON结果绑定到Component变量

时间:2016-11-16 18:40:43

标签: javascript angular ecmascript-6

我正在尝试一个必须从JSON文件中提取数据的简单组件。我几乎从生成的Fountain App复制功能,但由于某种原因我无法获得所需的结果。我有一个组件,如:

import {Component, Inject} from "@angular/core";
import {Http} from '@angular/http';

@Component({
  selector: 'body-selector',
  template: require('./body.html')
})

@Inject(Http)

export class BodyComponent {
  constructor(http: Http) {
    this.http = http;
    this.getText('app/texts/main.json').subscribe(result => {
    console.log(result);
    this.texts = result;
  });
  console.log(this.texts);
}
  getText(url) {
    return this.http.get(url).map(response => response.json());
  }
}

在第一个console.log我有[Object object] [Object object] [Object object],这是正确的,因为我在JSON中有三个条目。然而,在第二个我有undefined,这在浏览器中变成了错误。

Error in ./BodyComponent class BodyComponent - inline template:3:6 caused by: Cannot read property 'title' of undefined

我正在查看从喷泉应用程序生成的示例,但我无法得到我做错了什么。

3 个答案:

答案 0 :(得分:1)

你未定义,因为:

this.getText('app/texts/main.json')

是一个获取数据的异步调用,当它完成时,它会执行' subscribe'中的代码。块。所以this.text是空的,直到执行。这是预期的行为。

答案 1 :(得分:1)

您有多个问题:

  • 第一个undefined位于回调中,其中刚刚设置了this.texts。但是第二个是在回调之外,所以它不会。因此,您总是会看到*ngIf,因为......

  • ...您从未为null设置默认值,而您的模板显然没有任何默认值undefined处理this.textsHttp templateUrl,导致在回调之前发生错误。

以下是您的代码,重构为以空require开头(假设它应该是数组;请适应品味)并简化OnInit的注入。另请注意注释,并且我已使用import {Component, OnInit} from '@angular/core'; // note consistent quotes import {Http} from '@angular/http'; @Component({ selector: 'body-selector', templateUrl: './body.html', }) export class BodyComponent implements OnInit { texts: any[] = []; // start with an empty array constructor(private http: Http) { } // inject Http here, no need to assign to this ngOnInit() { this.http .get('app/texts/main.json') .map(response => response.json()) .subscribe(result => { console.log(result); // only log *inside* the callback this.texts = result; }); // outside the callback, the HTTP call hasn't yet finished } } 来避免ngIf<div class="main-container" *ngIf="texts"> ... </div> 在组件生命周期中稍后触发HTTP调用,而不是在构造函数中执行此操作。 / p>

y.Sheets("DTR").[a1].PasteSpecial

您还可以通过在HTML中使用Paste来解决此问题,以防止在数据出现之前加载元素。

SCNNode *node = [SCNNode node];

我强烈建议您浏览一下基本的Angular 2教程,以了解这些内容,请参阅例如the Tour of Heroes

答案 2 :(得分:-1)

使用数据或使用API​​调用的更好方法:

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';

@Injectable()
export class BodyService {
  private _requestOptions: RequestOptions;

  private static handleError(error: Response): ErrorObservable {
    return Observable.throw(error.json().error || 'Server error');
  }

  constructor(private http: Http) {
    const headers = new Headers({ 'Accept': 'application/json' });
    this._requestOptions = new RequestOptions({ headers: headers});
  }

  /**
   * [getJsonData will get data of json file: main.json ]
  */
  getJsonData() {
    return this.http.get('app/texts/main.json', this._requestOptions)
        .map(res => res.json())    //needs to add map for converting data in json format
        .catch(BodyService.handleError);
  }
}

现在在您的组件中注入此服务:

import {Component, OnInit} from '@angular/core';
import { BodyService } from './adminModules.service';

@Component({
  selector: 'body-selector',
  templateUrl: './body.html',
  providers: [BodyService]
})

export class BodyComponent implements OnInit {
texts: any = [];  // start with an empty array
errorMessage: any;

 constructor(private _bodyService: BodyService) {}

 ngOnInit() {
   this._bodyService.getJsonData()
    .subscribe(data => {
      this.texts = data;
      console.log('data', this.texts);
     }, error => {
        this.errorMessage = <any> error;
    })
  }

}

对于调用服务,您可以直接在构造函数中调用或创建一个方法,并在构造函数或您要调用的任何位置调用。

希望它对你有所帮助:))