简体   繁体   English

在 Angular 中使用 http.get() 从本地文件加载 JSON 内容 2

[英]Load JSON content from a local file with http.get() in Angular 2

I'm trying to load a local JSON file with http.get() in Angular 2. I tried something that I found here on Stack Overflow.我正在尝试使用 Angular 中的http.get()加载本地 JSON 文件 2. 我尝试了在 Stack Overflow 上找到的一些内容。 It looks like this:它看起来像这样:

This is my app.module.ts where I import the HttpModule and the JsonModule from @angular/http :这是我的app.module.ts ,我从@angular/http import HttpModuleJsonModule

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule, JsonpModule } from '@angular/http';
import { RouterModule, Routes } from '@angular/router';

import { AppComponent } from './app.component';
import { NavCompComponent } from './nav-comp/nav-comp.component';
import { NavItemCompComponent } from './nav-comp/nav-item-comp/nav-item-comp.component';


@NgModule({
    declarations: [
        AppComponent,
        NavCompComponent,
        NavItemCompComponent
    ],
    imports: [
        BrowserModule,
        FormsModule,
        HttpModule,
        JsonpModule,
        RouterModule.forRoot(appRoutes)
    ],
    providers: [],
    bootstrap: [AppComponent]
})

export class AppModule { }

In my component , I import Http and Response from @angular/http .在我的组件中,我从@angular/http import HttpResponse Then I have a function called loadNavItems() , where I try to load my JSON content with a relative path using http.get() and print the result with console.log() .然后我有一个名为loadNavItems()的 function,我尝试使用http.get()加载我的 JSON 内容,并使用console.log()打印结果。 The function is called in ngOnInit() : function 在ngOnInit()中调用:

import { Component, OnInit } from '@angular/core';
import { Http, Response } from '@angular/http';

@Component({
    selector: 'app-nav-comp',
    templateUrl: './nav-comp.component.html',
    styleUrls: ['./nav-comp.component.scss']
})
export class NavCompComponent implements OnInit {

    navItems: any;

    constructor(private http: Http) { }

    ngOnInit() {
        this.loadNavItems();
    }

    loadNavItems() {
        this.navItems = this.http.get("../data/navItems.json");
        console.log(this.navItems);
    }
}

My local JSON file looks like this:我的本地 JSON 文件如下所示:

[{
        "id": 1,
        "name": "Home",
        "routerLink": "/home-comp"
    },
    {
        "id": 2,
        "name": "Über uns",
        "routerLink": "/about-us-comp"
    },
    {
        "id": 3,
        "name": "Events",
        "routerLink": "/events-comp"
    },
    {
        "id": 4,
        "name": "Galerie",
        "routerLink": "/galery-comp"
    },
    {
        "id": 5,
        "name": "Sponsoren",
        "routerLink": "/sponsoring-comp"
    },
    {
        "id": 6,
        "name": "Kontakt",
        "routerLink": "/contact-comp"
    }
]

There aren't any errors in the console, and I just get this output:控制台中没有任何错误,我只得到这个 output:

在此处输入图像描述

In my HTML template I would like to loop the items like this:在我的HTML 模板中,我想像这样循环项目:

<app-nav-item-comp *ngFor="let item of navItems" [item]="item"></app-nav-item-comp>

I made this with a solution I found here on Stack Overflow, but why doesn't it work?我用我在 Stack Overflow 上找到的解决方案做了这个,但为什么它不起作用?

Edit relative path :编辑相对路径

I also get a problem with my relative path, but I'm sure it's the right one when I use ../data/navItems.json .我的相对路径也有问题,但我确信当我使用../data/navItems.json时它是正确的。 In the screenshot, you can see the nav-comp.component.ts file, where I load the JSON content using a relative path from the JSON file which is in the folder called data?在屏幕截图中,您可以看到nav-comp.component.ts文件,我在其中使用 JSON 文件的相对路径加载 JSON 内容,该文件位于名为数据的文件夹中? What's wrong?怎么了? Does the console print an 404 error, because it can't find my JSON file from the relative path?控制台是否打印 404 错误,因为它无法从相对路径中找到我的 JSON 文件?

在此处输入图像描述

For Angular 5+ only preform steps 1 and 4对于Angular 5+,仅预成型步骤14


In order to access your file locally in Angular 2+ you should do the following (4 steps):为了在Angular 2+ 中本地访问您的文件,您应该执行以下操作(4 个步骤):

[1] Inside your assets folder create a .json file, example: data.json [1]在您的资产文件夹中创建一个.json文件,例如: data.json

[2] Go to your angular.cli.json (angular.json in Angular 6+) inside your project and inside the assets array put another object (after the package.json object) like this: [2]转到项目中的angular.cli.json (Angular 6+ 中的 angular.json),然后在assets数组中放置另一个对象(在package.json对象之后),如下所示:

{ "glob": "data.json", "input": "./", "output": "./assets/" } { "glob": "data.json", "input": "./", "output": "./assets/" }

full example from angular.cli.json来自 angular.cli.json 的完整示例

"apps": [
    {
      "root": "src",
      "outDir": "dist",
      "assets": [
        "assets",
        "favicon.ico",
        { "glob": "package.json", "input": "../", "output": "./assets/" },
        { "glob": "data.json", "input": "./", "output": "./assets/" }
      ],

Remember, data.json is just the example file we've previously added in the assets folder (you can name your file whatever you want to)请记住, data.json只是我们之前在 assets 文件夹中添加的示例文件(您可以随意命名您的文件)

[3] Try to access your file via localhost. [3]尝试通过本地主机访问您的文件。 It should be visible within this address, http://localhost:your_port/assets/data.json它应该在这个地址中可见, http://localhost:your_port/assets/data.json

If it's not visible then you've done something incorrectly.如果它不可见,那么你做错了什么。 Make sure you can access it by typing it in the URL field in your browser before proceeding to step #4.在继续第 4 步之前,请确保您可以通过在浏览器的 URL 字段中输入它来访问它。

[4] Now preform a GET request to retrieve your .json file (you've got your full path .json URL and it should be simple) [4]现在执行 GET 请求以检索您的.json文件(您已经获得了完整路径.json URL,它应该很简单)

 constructor(private http: HttpClient) {}
        // Make the HTTP request:
        this.http.get('http://localhost:port/assets/data.json')
                 .subscribe(data => console.log(data));

You have to change你必须改变

loadNavItems() {
        this.navItems = this.http.get("../data/navItems.json");
        console.log(this.navItems);
    }

for为了

loadNavItems() {
        this.navItems = this.http.get("../data/navItems.json")
                        .map(res => res.json())
                        .do(data => console.log(data));
                        //This is optional, you can remove the last line 
                        // if you don't want to log loaded json in 
                        // console.
    }

Because this.http.get returns an Observable<Response> and you don't want the response, you want its content.因为this.http.get返回一个Observable<Response>而你不想要响应,你想要它的内容。

The console.log shows you an observable, which is correct because navItems contains an Observable<Response> . console.log显示了一个 observable,这是正确的,因为 navItems 包含一个Observable<Response>

In order to get data properly in your template, you should use async pipe.为了在模板中正确获取数据,您应该使用async管道。

<app-nav-item-comp *ngFor="let item of navItems | async" [item]="item"></app-nav-item-comp>

This should work well, for more informations, please refer to HTTP Client documentation这应该工作得很好,有关更多信息,请参阅HTTP 客户端文档

MY OWN SOLUTION我自己的解决方案

I created a new component called test in this folder:我在这个文件夹中创建了一个名为test的新component

在此处输入图片说明

I also created a mock called test.json in the assests folder created by angular cli (important):我还在angular cli创建的assests文件夹中创建了一个名为test.json的模拟(重要):

在此处输入图片说明

This mock looks like this:这个模拟看起来像这样:

[
        {
            "id": 1,
            "name": "Item 1"
        },
        {
            "id": 2,
            "name": "Item 2"
        },
        {
            "id": 3,
            "name": "Item 3"
        }
]

In the controller of my component test import follow rxjs like this在我的组件test import的控制器中,像这样遵循rxjs

import 'rxjs/add/operator/map'

This is important, because you have to map your response from the http get call, so you get a json and can loop it in your ngFor .这很重要,因为您必须从http get调用map您的response ,因此您将获得一个json并可以在您的ngFor循环它。 Here is my code how I load the mock data.这是我如何加载模拟数据的代码。 I used http get and called my path to the mock with this path this.http.get("/assets/mock/test/test.json") .我使用了http get并使用此路径this.http.get("/assets/mock/test/test.json")调用了我的模拟路径。 After this i map the response and subscribe it.在此之后,我map响应并subscribe它。 Then I assign it to my variable items and loop it with ngFor in my template .然后我将它分配给我的变量items并在我的template使用ngFor循环它。 I also export the type.我也导出类型。 Here is my whole controller code:这是我的整个控制器代码:

import { Component, OnInit } from "@angular/core";
import { Http, Response } from "@angular/http";
import 'rxjs/add/operator/map'

export type Item = { id: number, name: string };

@Component({
  selector: "test",
  templateUrl: "./test.component.html",
  styleUrls: ["./test.component.scss"]
})
export class TestComponent implements OnInit {
  items: Array<Item>;

  constructor(private http: Http) {}

  ngOnInit() {
    this.http
      .get("/assets/mock/test/test.json")
      .map(data => data.json() as Array<Item>)
      .subscribe(data => {
        this.items = data;
        console.log(data);
      });
  }
}

And my loop in it's template :我在它的template循环:

<div *ngFor="let item of items">
  {{item.name}}
</div>

It works as expected!它按预期工作! I can now add more mock files in the assests folder and just change the path to get it as json .我现在可以在 assests 文件夹中添加更多模拟文件,只需更改路径即可将其获取为json Notice that you have also to import the HTTP and Response in your controller.请注意,您还必须在控制器中导入HTTPResponse The same in you app.module.ts (main) like this:在你 app.module.ts (main) 中同样如此:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpModule, JsonpModule } from '@angular/http';


import { AppComponent } from './app.component';
import { TestComponent } from './components/molecules/test/test.component';


@NgModule({
  declarations: [
    AppComponent,
    TestComponent
  ],
  imports: [
    BrowserModule,
    HttpModule,
    JsonpModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

I found that the simplest way to achieve this is by adding the file.json under folder: assets .我发现实现这一点的最简单方法是在文件夹下添加file.jsonassets

No need to edit: .angular-cli.json无需编辑: .angular-cli.json

Service

@Injectable()
export class DataService {
  getJsonData(): Promise<any[]>{
    return this.http.get<any[]>('http://localhost:4200/assets/data.json').toPromise();
  }
}

Component

private data: any[];

constructor(private dataService: DataService) {}

ngOnInit() {
    data = [];
    this.dataService.getJsonData()
      .then( result => {
        console.log('ALL Data: ', result);
        data = result;
      })
      .catch( error => {
        console.log('Error Getting Data: ', error);
      });
  }

Extra:额外的:

Ideally, you only want to have this in a dev environment so to be bulletproof.理想情况下,您只想在开发环境中使用它,以便防弹。 create a variable on your environment.ts在您的environment.ts上创建一个变量

export const environment = {
  production: false,
  baseAPIUrl: 'http://localhost:4200/assets/data.json'
};

Then replace the URL on the http.get for ${environment.baseAPIUrl}然后将http.get上的 URL 替换为${environment.baseAPIUrl}

And the environment.prod.ts can have the production API URL.并且environment.prod.ts可以有生产 API URL。

Hope this helps!希望这可以帮助!

  • create/move json under assetsassets下创建/移动 json
  • implement method in service在服务中实现方法
  private URL = './assets/navItems.json'; // ./ is important!

  constructor(private httpClient: HttpClient) {
  }

  fetch(): Observable<any> {
      return this.httpClient.get(this.URL);
  }
  • call it in component在组件中调用它
  private navItems: NavItems[];

  constructor(private navItemsService: NavItemsService) { }

  ngOnInit(): void {
    this.publicationService.fetch().subscribe(navItems => this.navItems = navItems);
  }

I you want to put the response of the request in the navItems .我想将请求的响应放在navItems Because http.get() return an observable you will have to subscribe to it.因为http.get()返回一个 observable,所以你必须订阅它。

Look at this example:看这个例子:

 // version without map this.http.get("../data/navItems.json") .subscribe((success) => { this.navItems = success.json(); }); // with map import 'rxjs/add/operator/map' this.http.get("../data/navItems.json") .map((data) => { return data.json(); }) .subscribe((success) => { this.navItems = success; });

Put your navItems.json in "assets" folder.将您的 navItems.json 放在“assets”文件夹中。 Angular knows how to look inside the assets folder. Angular 知道如何查看资产文件夹内部。 So instead of:所以而不是:

loadNavItems() {
    this.navItems = this.http.get("../data/navItems.json");
    console.log(this.navItems);
}

Change the path to simply:将路径更改为简单:

    loadNavItems() {
    this.navItems = this.http.get("assets/navItems.json");
    console.log(this.navItems);
}

If you are using Angular CLI: 7.3.3 What I did is, On my assets folder I put my fake json data then on my services I just did this.如果您使用的是Angular CLI: 7.3.3我所做的是,在我的资产文件夹中,我将虚假的 json 数据放在我的服务中,我只是这样做了。

const API_URL = './assets/data/db.json';

getAllPassengers(): Observable<PassengersInt[]> {
    return this.http.get<PassengersInt[]>(API_URL);
  }

在此处输入图片说明

试试: this.navItems = this.http.get("data/navItems.json");

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

相关问题 无法使用Angular对本地JSON文件发出$ http.get请求 - Unable to make a $http.get request to a local JSON file using Angular Webpack无法加载json文件,如何找到本地json文件并使用AngularJS使用http.get加载 - Webpack can't load the json file, how to locate the local json file and load that using http.get with AngularJS 使用API​​中的$ http.get进行Angular.js本地开发 - Angular.js local development with $http.get from API 如何使用Angular的$ http.get从JSON文件中获取特定数据 - How to get specific data from a JSON file using Angular's $http.get Angular 1.6 $ http.get无法从json读取 - Angular 1.6 $http.get unable to read from json 从$ http.get调用中反复调用静态.json文件的性能问题 - Performance concern with static .json file getting called repeatedly from $http.get call with angular Angular-在页面加载时触发$ http.get - Angular - Fire $http.get on page load 从服务器下载带有角度$ http.get的文件 - Download file from server with angular $http.get 来自本地服务器上项目的servlet的Angular Http.get请求(json数据正确返回但未显示,但可与模拟api一起使用) - Angular Http.get request from servlet of project on local server (json data returns correctly, but not displaying, does work with a mock api) Angular.js-$ http.get-使用文件中的缓存 - Angular.js - $http.get - use cache from file
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM