我正在使用Angular 2应用程序,我尝试使用JSON数据,本地/模拟或通过HTTP获取,并将其显示在组件上。我有一个可注射服务,可以进行提取/模拟 -
import { Injectable } from 'angular2/core';
@Injectable()
export class TestService {
testString:string = "";
testDetails: string = "";
constructor() { }
getTestDetails(): Promise<string> {
this.testDetails = {
"status": "success",
"message": "Data save successful",
"data": {
"Random_Data_1": "Random Data 1",
"Random_Data_2": "Random Data 2"
}
};
return Promise.resolve(JSON.stringify(this.propertyDetails));
}
}
然后我有一个通过依赖注入使用服务的组件 -
import { Component, OnInit } from 'angular2/core';
import {TestService} from "./test.service";
@Component({
selector: 'test',
templateUrl: './test.component.html',
styleUrls: []
})
export class TestComponent implements OnInit {
testDetails: string = "";
constructor(private testService: TestService) { }
ngOnInit() {
this.display();
}
display(): void {
this.testService.getTestDetails()
.then(
testDetails => {
this.testDetails = JSON.parse(testDetails);
},
errorMessage => {
console.error("Something failed trying to get test details");
console.error(errorMessage);
}
);
}
}
组件HTML -
<div class="content">
<p> Test Details </p>
<p> {{ testDetails.data.Random_Data_1 }} </p>
</div>
问题是,HTML试图在testDetails JSON中显示项目时出错。我最初使用它与md-tabs,所以第一次尝试会出错,但其他选项卡会读取数据。此外,发生错误时将调用ngOnInit两次。我把它缩小到了进入的数据和引起我头痛的对象类型。
我知道我可以创建一个Details类并声明类型为Details的testDetails,然后将JSON数据映射到类中,但问题是,我想使用通用数据,并且只知道一些组件存在于数据中。有没有办法读取JSON,并使用数据而无需为每个场景定义单独的类?
我有一个最基本的东西设置的plunker。实际设置在我的本地系统上运行良好,直到我尝试访问HTML中的JSON数据,此时浏览器抛出了一个神秘的错误。骨架代码甚至不能在Plunker上运行。也就是说,Plunker中的结构定义了我的应用程序的结构和数据流。 Plunker with the basic setup
实现这一目标的最佳方法是什么?这样做的标准/最佳做法是什么?
答案 0 :(得分:1)
使用
<p *ngIF="testDetails.data.Random_Data_1 "> {{ testDetails.data.Random_Data_1 }} </p>
这是因为最初没有数据。希望这可以帮到你。
答案 1 :(得分:1)
Throwing another option out there, since you asked about best way to achieve this. Might not be the best idea, this is subjective ;) But if I were you...
Thinking about the future, where you will use real backend, it could be nice to use mock json file. If/when you move over to a real backend, you wouldn't basically need to change anything else but the url of the requests :)
So I set up a simple example for you. Here I used Observables, but you can use Promises if you prefer that. Here's more info on HTTP if you want/need to read up on that. Most important thing is that you have the HttpModule
imported in your app module.
You have your file with JSON and in your service make http-requests to that:
getTestDetails() {
return this.http.get('src/data.json')
.map(res => res.json())
}
Your display-method:
display() {
this.testService.getTestDetails()
.subscribe(data => {
this.testDetails = data;
});
}
And in the template use the safe navigation operator to safeguard null/undefined values:
<div class="content">
<p> Test Details </p>
<p> {{ testDetails?.data?.Random_Data_1 }} </p>
</div>
Here's a
As said, this is to give another approach on how to implement the things you want to achieve, and this would probably be my preferred way :)