简体   繁体   English

Angular 2-使用/显示通过HTTP获取或模拟的JSON数据

[英]Angular 2 - Using/displaying JSON data fetched through HTTP, or mocked

I'm working on an Angular 2 application, and I'm trying to use JSON data, either local/mocked or fetched via HTTP, and display it on a component. 我正在使用Angular 2应用程序,并且尝试使用本地/模拟或通过HTTP获取的JSON数据,并将其显示在组件上。 I have an injectable service that will do the fetching/mocking - 我有一个可注射的服务,可以进行提取/模拟-

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));
  }
}

And then I have a component that uses the service via Dependency Injection - 然后我有一个通过依赖注入使用服务的组件-

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);
        }
      );
  }
}

The component HTML - 组件HTML-

<div class="content">
  <p> Test Details </p>
  <p> {{ testDetails.data.Random_Data_1 }} </p>
</div>

The problem is, the HTML is erroring out trying to display the items in the testDetails JSON. 问题是,HTML尝试在testDetails JSON中显示项目时出错。 I initially used it with md-tabs, so the first try would error out, but the other tabs would read the data fine. 我最初将它与md-tabs一起使用,因此第一次尝试会出错,但是其他选项卡会很好地读取数据。 Also, the ngOnInit would be called twice when the error occurs. 此外,发生错误时,将两次调用ngOnInit。 I have narrowed it down to the data coming in and the object types that is causing me the headache. 我将其范围缩小到输入的数据和导致我头痛的对象类型。

I know I can create a Details class and declare testDetails of type Details, and then map the JSON data into the class, but the thing is, I want to work with generic data, and only know a few components that will be present in the data. 我知道我可以创建一个Details类并声明类型为Details的testDetails,然后将JSON数据映射到该类中,但事实是,我想使用通用数据,并且只知道其中的一些组件。数据。 Is there a way to read the JSON, and use the data without having to define a separate class for each scenario ? 有没有一种方法可以读取JSON和使用数据,而不必为每种情况定义一个单独的类?

I have a plunker with the most basic stuff set up. 我有一个最基本的东西设置的朋克。 The actual setup runs fine on my local system up until where I try to access the JSON data in the HTML, at which point the browser throws a cryptic error. 实际的设置在我的本地系统上运行良好,直到尝试访问HTML中的JSON数据为止,此时浏览器引发了一个神秘的错误。 The skeleton code doesn't even run on Plunker. 框架代码甚至无法在Plunker上运行。 That said, the structure in the Plunker defines the structure of my app and the data flow. 也就是说,Plunker中的结构定义了我的应用程序的结构和数据流。 Plunker with the basic setup 基本设置的柱塞

What is the best way to achieve this ? 实现此目标的最佳方法是什么? What is the standard/best practice to do this ? 这样做的标准/最佳实践是什么?

Use 采用

<p *ngIF="testDetails.data.Random_Data_1 "> {{ testDetails.data.Random_Data_1 }} </p>

This is because there is no data initially.Hope this helps you. 这是因为最初没有数据。希望对您有帮助。

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. 考虑到未来,您将在哪里使用真正的后端,所以可以使用模拟json文件。 If/when you move over to a real backend, you wouldn't basically need to change anything else but the url of the requests :) 如果/当您移至真正的后端时,除了请求的URL之外,您基本上不需要更改其他任何内容:)

So I set up a simple example for you. 因此,我为您建立了一个简单的示例。 Here I used Observables, but you can use Promises if you prefer that. 在这里,我使用了Observables,但如果愿意,可以使用Promises。 Here's more info on HTTP if you want/need to read up on that. 如果您想/需要阅读有关HTTP更多信息,请参见这里。 Most important thing is that you have the HttpModule imported in your app module. 最重要的是,您已在应用程序模块中导入了HttpModule

You have your file with JSON and in your service make http-requests to that: 您的文件带有JSON,并在服务中对此进行了HTTP请求:

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: 并在模板中使用安全导航运算符来保护null / undefined值:

<div class="content">
  <p> Test Details </p>
  <p> {{ testDetails?.data?.Random_Data_1 }} </p>
</div>

Here's a 这是一个

Demo 演示

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 :) 如前所述,这是提供另一种方法来实现您想要实现的目标,这可能是我的首选方式:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM