我正在尝试一个必须从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
我正在查看从喷泉应用程序生成的示例,但我无法得到我做错了什么。
答案 0 :(得分:1)
你未定义,因为:
this.getText('app/texts/main.json')
是一个获取数据的异步调用,当它完成时,它会执行' subscribe'中的代码。块。所以this.text是空的,直到执行。这是预期的行为。
答案 1 :(得分:1)
您有多个问题:
第一个undefined
位于回调中,其中刚刚设置了this.texts
。但是第二个是在回调之外,所以它不会。因此,您总是会看到*ngIf
,因为......
...您从未为null
设置默认值,而您的模板显然没有任何默认值undefined
处理this.texts
或Http
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;
})
}
}
对于调用服务,您可以直接在构造函数中调用或创建一个方法,并在构造函数或您要调用的任何位置调用。
希望它对你有所帮助:))