使用 angular 2 中的 http.get() 从本地文件加载 json

IT技术 javascript html json angular http
2021-03-09 02:59:27

我正在尝试使用http.get()angular 2加载本地 json 。我尝试了一些东西,我在堆栈中找到了这些东西。它看起来像这样:

这是我的app.module.ts,我importHttpModuleJsonModule来自@angular/http

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 { }

在我的组件中Iimport HttpResponse来自@angular/http. 然后,我有调用的函数loadNavItems(),在这里我尝试使用加载的json使用相对路径http.get(),并打印其结果console.log()该函数被调用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);
    }
}

我的本地 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"
    }
]

控制台中没有错误,我只是得到这个输出:在此处输入图片说明

在我的html 模板中,我想循环这样的项目:

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

我用我在堆栈上找到的解决方案做了这个,但我不知道为什么它不起作用?

编辑相对路径: 我的相对路径也有问题,但我确信当我使用../data/navItems.json. 在屏幕截图中,您可以设置 nav-comp.component.ts,我在其中使用名为 data 的文件夹中的 json 文件的相对路径加载 json?怎么了,控制台打印404错误,因为从相对路径找不到我的json文件?

在此处输入图片说明

6个回答

对于Angular 5+,仅预成型步骤14


为了在Angular 2+ 中本地访问您的文件,您应该执行以下操作(4 个步骤):

[1]在您的资产文件夹中创建一个.json文件,例如:data.json

[2]转到项目中的angular.cli.json(Angular 6+ 中的 angular.json),然后在assets数组中放置另一个对象(在package.json对象之后),如下所示:

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

来自 angular.cli.json 的完整示例

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

请记住,data.json只是我们之前在资产文件夹中添加的示例文件(您可以随意命名您的文件)

[3]尝试通过本地主机访问您的文件。它应该在这个地址中可见,http://localhost:your_port/assets/data.json

如果它不可见,那么你做错了什么。在继续第 4 步之前,确保您可以通过在浏览器的 URL 字段中输入它来访问它。

[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));
我今天会尝试并通知您。
2021-04-17 02:59:27
嗨 Eugen,我稍后会尝试,希望这有效!谢谢
2021-04-21 02:59:27
在 Angular 5 中,您需要做的就是将 .json 文件放在资产文件夹下,如步骤 1 所述,并直接在您的服务调用中引用它,如步骤 4 所述。它对我有用。
2021-04-30 02:59:27
@kingforever 你想把它放在哪里?资产文件适用于此类场景。
2021-05-08 02:59:27
这是一个非常巧妙的解决方案。谢谢你的回答。
2021-05-12 02:59:27

你必须改变

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

为了

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.
    }

因为this.http.get返回 anObservable<Response>并且您不想要响应,所以您想要它的内容。

console.log你展示了一个可观察到的,这是正确的,因为navItems包含Observable<Response>

为了在模板中正确获取数据,您应该使用async管道。

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

这应该工作得很好,有关更多信息,请参阅HTTP 客户端文档

2021-04-18 02:59:27
“Observable<Response> 类型上不存在属性映射”?
2021-04-21 02:59:27
添加import 'rxjs/add/operator/map';您的导入,或import {Observable} from 'rxjs';更改navItems: anynavItems:Observable<any>
2021-04-25 02:59:27
@MrBuggy 如果您想对控制台进行输入,我可以编辑答案以添加一个,但我认为您的主要问题是在模板中呈现内容,因此我删除了 console.log。
2021-04-26 02:59:27
我导入了“import 'rxjs/add/operator/map';”,错误不再存在但控制台中的输出是一样的?
2021-05-08 02:59:27

我自己的解决方案

在这个文件夹中创建了一个新的component调用test

在此处输入图片说明

我还创建了一个test.json(重要)assests创建文件夹中调用的模拟angular cli

在此处输入图片说明

这个模拟看起来像这样:

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

在我的组件的控制器test import如下rxjs这样

import 'rxjs/add/operator/map'

这一点很重要,因为你要mapresponsehttp get电话,所以你得到一个json在你的和可循环它ngFor这是我如何加载模拟数据的代码。我使用http get并使用此路径调用了我的模拟路径this.http.get("/assets/mock/test/test.json")在这之后我map的回应和subscribe它。然后我将它分配给我的变量itemsngFor在我的template. 我也导出类型。这是我的整个控制器代码:

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

我的循环是template

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

它按预期工作!我现在可以在assests文件夹中添加更多模拟文件,只需更改路径即可将其作为json. 请注意,您还必须在控制器中导入HTTPResponse在你 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 { }
.map(data => data.json() as Array<Item>) 这一行告诉我 Object 没有方法 'json'
2021-04-27 02:59:27
@RanLottem 您是否正确导出了“项目”类型?
2021-05-02 02:59:27
默认的 get 返回 json,不需要做 .json()
2021-05-04 02:59:27
无论我在这一行中转换为哪种类型,data.json() 仍然会给出“对象”没有 json 属性的错误。
2021-05-10 02:59:27

我发现实现这一点的最简单方法是在文件夹下添加file.jsonassets

无需编辑: .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);
      });
  }

额外的:

理想情况下,您只想在开发环境中使用它,以便防弹。在你的上创建一个变量environment.ts

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

然后将http.get上的 URL 替换${environment.baseAPIUrl}

并且environment.prod.ts可以具有生产 API URL。

希望这可以帮助!

将您的 navItems.json 放在“assets”文件夹中。Angular 知道如何查看资产文件夹内部。所以而不是:

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

将路径更改为简单:

    loadNavItems() {
    this.navItems = this.http.get("assets/navItems.json");
    console.log(this.navItems);
}
感谢菲利普的冷静建议..它帮助了我:-)
2021-05-10 02:59:27