[英]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
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 { }
In my component , I import
Http
and Response
from @angular/http
.在我的组件中,我从
@angular/http
import
Http
和Response
。 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+,仅预成型步骤1和4
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.请注意,您还必须在控制器中导入
HTTP
和Response
。 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.json : assets 。
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);
});
}
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!希望这可以帮助!
assets
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);
}
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.