![](/img/trans.png)
[英]Unable to make a $http.get request to a local JSON file using Angular
[英]Load JSON content from a local file with http.get() in Angular 2
我正在尝试使用 Angular 中的http.get()
加载本地 JSON 文件 2. 我尝试了在 Stack Overflow 上找到的一些内容。 它看起来像这样:
这是我的app.module.ts
,我从@angular/http
import
HttpModule
和JsonModule
:
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 { }
在我的组件中,我从@angular/http
import
Http
和Response
。 然后我有一个名为loadNavItems()
的 function,我尝试使用http.get()
加载我的 JSON 内容,并使用console.log()
打印结果。 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);
}
}
我的本地 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"
}
]
控制台中没有任何错误,我只得到这个 output:
在我的HTML 模板中,我想像这样循环项目:
<app-nav-item-comp *ngFor="let item of navItems" [item]="item"></app-nav-item-comp>
我用我在 Stack Overflow 上找到的解决方案做了这个,但为什么它不起作用?
编辑相对路径:
我的相对路径也有问题,但我确信当我使用../data/navItems.json
时它是正确的。 在屏幕截图中,您可以看到nav-comp.component.ts文件,我在其中使用 JSON 文件的相对路径加载 JSON 内容,该文件位于名为数据的文件夹中? 怎么了? 控制台是否打印 404 错误,因为它无法从相对路径中找到我的 JSON 文件?
对于Angular 5+,仅预成型步骤1和4
为了在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只是我们之前在 assets 文件夹中添加的示例文件(您可以随意命名您的文件)
[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));
你必须改变
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
返回一个Observable<Response>
而你不想要响应,你想要它的内容。
console.log
显示了一个 observable,这是正确的,因为 navItems 包含一个Observable<Response>
。
为了在模板中正确获取数据,您应该使用async
管道。
<app-nav-item-comp *ngFor="let item of navItems | async" [item]="item"></app-nav-item-comp>
这应该工作得很好,有关更多信息,请参阅HTTP 客户端文档
我自己的解决方案
我在这个文件夹中创建了一个名为test
的新component
:
我还在angular cli
创建的assests
文件夹中创建了一个名为test.json
的模拟(重要):
这个模拟看起来像这样:
[
{
"id": 1,
"name": "Item 1"
},
{
"id": 2,
"name": "Item 2"
},
{
"id": 3,
"name": "Item 3"
}
]
在我的组件test
import
的控制器中,像这样遵循rxjs
import 'rxjs/add/operator/map'
这很重要,因为您必须从http get
调用map
您的response
,因此您将获得一个json
并可以在您的ngFor
循环它。 这是我如何加载模拟数据的代码。 我使用了http
get
并使用此路径this.http.get("/assets/mock/test/test.json")
调用了我的模拟路径。 在此之后,我map
响应并subscribe
它。 然后我将它分配给我的变量items
并在我的template
使用ngFor
循环它。 我也导出类型。 这是我的整个控制器代码:
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
。 请注意,您还必须在控制器中导入HTTP
和Response
。 在你 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 { }
我发现实现这一点的最简单方法是在文件夹下添加file.json : assets 。
无需编辑: .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。
希望这可以帮助!
assets
下创建/移动 json private URL = './assets/navItems.json'; // ./ is important!
constructor(private httpClient: HttpClient) {
}
fetch(): Observable<any> {
return this.httpClient.get(this.URL);
}
private navItems: NavItems[];
constructor(private navItemsService: NavItemsService) { }
ngOnInit(): void {
this.publicationService.fetch().subscribe(navItems => this.navItems = navItems);
}
我想将请求的响应放在navItems
。 因为http.get()
返回一个 observable,所以你必须订阅它。
看这个例子:
// 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; });
将您的 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);
}
试试: this.navItems = this.http.get("data/navItems.json");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.